2021-01-13 13:24:47 +00:00
|
|
|
//! The Vesta and iso-Vesta elliptic curve groups.
|
|
|
|
|
|
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
|
|
|
|
|
|
use super::{Eq, EqAffine, Fp, Fq, IsoEq, IsoEqAffine};
|
|
|
|
|
use crate::arithmetic::{FieldExt, SimplifiedSWUWithDegree3Isogeny};
|
|
|
|
|
|
|
|
|
|
/// The base field of the Vesta and iso-Vesta curves.
|
|
|
|
|
pub type Base = Fq;
|
|
|
|
|
|
|
|
|
|
/// The scalar field of the Vesta and iso-Vesta curves.
|
|
|
|
|
pub type Scalar = Fp;
|
2020-12-03 20:45:13 +00:00
|
|
|
|
|
|
|
|
/// A Vesta point in the projective coordinate space.
|
2021-01-13 13:24:47 +00:00
|
|
|
pub type Point = Eq;
|
2020-12-03 20:45:13 +00:00
|
|
|
|
|
|
|
|
/// A Vesta point in the affine coordinate space (or the point at infinity).
|
2021-01-13 13:24:47 +00:00
|
|
|
pub type Affine = EqAffine;
|
|
|
|
|
|
|
|
|
|
/// An iso-Vesta point in the projective coordinate space.
|
|
|
|
|
pub type IsoPoint = IsoEq;
|
|
|
|
|
|
|
|
|
|
/// A iso-Vesta point in the affine coordinate space (or the point at infinity).
|
|
|
|
|
pub type IsoAffine = IsoEqAffine;
|
|
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
|
/// The iso-Vesta -> Vesta degree 3 isogeny map.
|
2021-02-02 16:26:08 +00:00
|
|
|
pub static ref MAP: SimplifiedSWUWithDegree3Isogeny<Base, Affine, IsoAffine> = {
|
2021-01-13 13:24:47 +00:00
|
|
|
let isogeny_constants: [Base; 13] = [
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0x43cd42c800000001,
|
|
|
|
|
0x0205dd51cfa0961a,
|
|
|
|
|
0x8e38e38e38e38e39,
|
|
|
|
|
0x38e38e38e38e38e3,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0x8b95c6aaf703bcc5,
|
|
|
|
|
0x216b8861ec72bd5d,
|
|
|
|
|
0xacecf10f5f7c09a2,
|
|
|
|
|
0x1d935247b4473d17,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0xaeac67bbeb586a3d,
|
|
|
|
|
0xd59d03d23b39cb11,
|
|
|
|
|
0xed7ee4a9cdf78f8f,
|
|
|
|
|
0x18760c7f7a9ad20d,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0xfb539a6f0000002b,
|
|
|
|
|
0xe1c521a795ac8356,
|
|
|
|
|
0x1c71c71c71c71c71,
|
|
|
|
|
0x31c71c71c71c71c7,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0xb7284f7eaf21a2e9,
|
|
|
|
|
0xa3ad678129b604d3,
|
|
|
|
|
0x1454798a5b5c56b2,
|
|
|
|
|
0x0a2de485568125d5,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0xf169c187d2533465,
|
|
|
|
|
0x30cd6d53df49d235,
|
|
|
|
|
0x0c621de8b91c242a,
|
|
|
|
|
0x14735171ee542778,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0x6bef1642aaaaaaab,
|
|
|
|
|
0x5601f4709a8adcb3,
|
|
|
|
|
0xda12f684bda12f68,
|
|
|
|
|
0x12f684bda12f684b,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0x8bee58e5fb81de63,
|
|
|
|
|
0x21d910aefb03b31d,
|
|
|
|
|
0xd6767887afbe04d1,
|
|
|
|
|
0x2ec9a923da239e8b,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0x4986913ab4443034,
|
|
|
|
|
0x97a3ca5c24e9ea63,
|
|
|
|
|
0x66d1466e9de10e64,
|
|
|
|
|
0x19b0d87e16e25788,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0x8f64842c55555533,
|
|
|
|
|
0x8bc32d36fb21a6a3,
|
|
|
|
|
0x425ed097b425ed09,
|
|
|
|
|
0x1ed097b425ed097b,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0x58dfecce86b2745e,
|
|
|
|
|
0x06a767bfc35b5bac,
|
|
|
|
|
0x9e7eb64f890a820c,
|
|
|
|
|
0x2f44d6c801c1b8bf,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0xd43d449776f99d2f,
|
|
|
|
|
0x926847fb9ddd76a1,
|
|
|
|
|
0x252659ba2b546c7e,
|
|
|
|
|
0x3d59f455cafc7668,
|
|
|
|
|
]),
|
|
|
|
|
Base::from_raw([
|
|
|
|
|
0x8c46eb20fffffde5,
|
|
|
|
|
0x224698fc0994a8dd,
|
|
|
|
|
0x0000000000000000,
|
|
|
|
|
0x4000000000000000,
|
|
|
|
|
]),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
let z = -Base::from_u64(13);
|
|
|
|
|
SimplifiedSWUWithDegree3Isogeny::new(&z, &isogeny_constants)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_map_to_curve_vesta() {
|
|
|
|
|
use crate::arithmetic::{Curve, CurveAffine, HashToCurve, Shake128};
|
|
|
|
|
use std::collections::HashSet;
|
|
|
|
|
|
|
|
|
|
assert!(MAP.minus_b_over_a * IsoAffine::a() == -IsoAffine::b());
|
|
|
|
|
assert!(MAP.b_over_za * MAP.z * IsoAffine::a() == IsoAffine::b());
|
|
|
|
|
assert!(MAP.theta.square() * Base::ROOT_OF_UNITY == MAP.z);
|
2020-12-03 20:45:13 +00:00
|
|
|
|
2021-01-13 13:24:47 +00:00
|
|
|
let set: HashSet<_> = (0..10000)
|
|
|
|
|
.map(|i| MAP.map_to_curve(&Base::from(i)).to_affine())
|
|
|
|
|
.collect();
|
|
|
|
|
assert!(set.len() == 10000);
|
2020-12-03 20:45:13 +00:00
|
|
|
|
2021-01-13 13:24:47 +00:00
|
|
|
let hash = MAP.hash_to_curve("z.cash:test", Shake128::default());
|
|
|
|
|
let p: Point = hash(b"hello");
|
|
|
|
|
let (x, y, z) = p.jacobian_coordinates();
|
|
|
|
|
println!("{:?}", p);
|
|
|
|
|
assert!(
|
|
|
|
|
format!("{:?}", x) == "0x3984612258b3b43b4f6e046f7f796bbd35ffd8908804bcf47b9537d3ec7645c9"
|
|
|
|
|
);
|
|
|
|
|
assert!(
|
|
|
|
|
format!("{:?}", y) == "0x2573c035293d745a288a65a7a37709ef99bcf31b77cfb3a1126a61e3adeebc4b"
|
|
|
|
|
);
|
|
|
|
|
assert!(
|
|
|
|
|
format!("{:?}", z) == "0x1cb99da94a634842b09a3ee1e5b462233e1fc23d0b357ec7fb0d1c409be30720"
|
|
|
|
|
);
|
|
|
|
|
}
|