1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use crate::internal::fp::{fp256_unsafe_from, fp480_unsafe_from};
use crate::internal::fp2elem::Fp2Elem;
use crate::internal::homogeneouspoint::HomogeneousPoint;
use crate::internal::homogeneouspoint::TwistedHPoint;
use gridiron::fp_256::Monty as Monty256;
use gridiron::fp_480::Monty as Monty480;
use lazy_static::lazy_static;
use num_traits::identities::One;
use num_traits::identities::Zero;
/// Points that are used in our core algorithm for for `FP`.
///
/// `g1` - the point which is in Fp2 and is used in the pairing.
/// `hash_element` - another point in Fp2 that is used for hashing.
/// `generator` - the generator point over FP.
#[derive(Debug)]
pub struct CurvePoints<FP> {
pub generator: HomogeneousPoint<FP>,
pub g1: TwistedHPoint<FP>,
pub hash_element: TwistedHPoint<FP>,
}
lazy_static! {
pub static ref FP_256_CURVE_POINTS: CurvePoints<Monty256> = CurvePoints {
// Fixed point in cyclic group G1 (the trace zero subgroup).
// Start with a point that is on the twisted curve y^2 = x^3 + (3 / (u + 3)).
// Turns out u + 1 is a valid x, with y = sqrt(x^3 + (3 / (u + 3)).
// Take (x,y) and multiply by (p + p - r) to get an r-torsion element of the twisted curve over FP2.
// Compute the anti-trace map of that r-torsion element to get a point in the trace-zero subgroup.
generator: HomogeneousPoint::new(One::one(), Monty256::from(2u8),),
g1: TwistedHPoint {
x: Fp2Elem {
//"25743265030535080187440590897139396943782163562799308681850377411492232521347",
elem1: fp256_unsafe_from("38ea2bf1e67ebb77fae32f89096b96cc8912bf8b02baccca22ccdd9bf6536683").to_monty(),
//34056889713323967780338301808336650802977437253339894663986165323395183925712
elem2: fp256_unsafe_from("4b4b8437fabcdd026eeb59e9f6baf17bedb2d3cae8f4dc6baf3704498087d9d0").to_monty()
},
y: Fp2Elem {
//36332093629799712472233840570439767783123758424653318224159027848500552319214
elem1: fp256_unsafe_from("50533c7b970d1b6e0374b55e8f96013a5ff8b25c7c51df6552093717d80ec0ee").to_monty(),
//19100300358747584658695151329066047798696640594509146799364306658205997167318
elem2: fp256_unsafe_from("2a3a630bb4d90e84802b412c45886566c7a1297bd46b22dd19f949aeed7b72d6").to_monty()
},
z: Fp2Elem {
//11969434517458907073927619028753373626677015846219303340439317866996854601254
elem1: fp256_unsafe_from("1a7675b952f7801f1895497dcc1f168d17f7214761909e23386d349ab952b626").to_monty(),
//14774454666095297364611775449425506027744765805321334870185419948913527571534
elem2: fp256_unsafe_from("20aa0b8534909adae8a0142c3118302a42460c7232af903f0211927a97a3444e").to_monty()
}
},
// Used to hash integers to a point in FP2
// Generated by multiplying g1 by the SHA256 hash of the date/time "Mon Feb 19 16:30:21 MST 2018\n",
// encoded in ASCII/UTF-8, converted to a BigInt.
hash_element: TwistedHPoint {
x: Fp2Elem {
//26115920809144023111516349163868890892335785984202627188956566235163006540541
elem1: fp256_unsafe_from("39bd165cf62008931544afcc46e7c4067a9c36f3bf6da3f60824042670471afd").to_monty(),
//15905362109061908101726321997764649315090633150407344591241408991746779381256
elem2: fp256_unsafe_from("232a1dada370347e57083bfc16fff22e7ff743d6ebae8eeba05ad501df5dfe08").to_monty()
},
y: Fp2Elem {
//4632230948348518150642153940906247958418069554996068756252789717528925762701
elem1: fp256_unsafe_from("a3dbff3400c6b5d254d4a8737b0272726bef7612168750d945512ecab74f48d").to_monty(),
//3026141039160762752629025637420408604709576372807872293769066469244216243501
elem2: fp256_unsafe_from("6b0bc318d9331d01ae6646f9b0d6cfe1c8b0e4eaee542fe03a8302f4a83752d").to_monty()
},
z: Fp2Elem {
//43872202626887887868122322275088633257981831137687656289783477940483447530228
elem1: fp256_unsafe_from("60fec9664750a01047481318531471ab94ddf69c82b1cc92dea03735192722f4").to_monty(),
//20191379131685497308054970475671582162258136917730106438050079114233947942452
elem2: fp256_unsafe_from("2ca3ea64a93d8451fb631c6923796388179f2ef65d72a05dd36af235146cee34").to_monty()
}
}
};
pub static ref FP_480_CURVE_POINTS: CurvePoints<Monty480> =
CurvePoints {
// Fixed point in cyclic group G1 (the trace zero subgroup).
// Start with a point that is on the twisted curve y^2 = x^3 + (3 / (u + 3)).
// Turns out u + 1 is a valid x, with y = sqrt(x^3 + (3 / (u + 3)).
// Take (x,y) and multiply by (p + p - r) to get an r-torsion element of the twisted curve over FP2.
// Compute the anti-trace map of that r-torsion element to get a point in the trace-zero subgroup.
generator: HomogeneousPoint::new(Monty480::from(1u8), Monty480::from(2u8),),
g1: TwistedHPoint {
x: Fp2Elem {
// 2836796539847730496121374298065944583953504150765508351672461175175719456840753019328265331693934514908570706456436537314841014056269083482678066
elem1: fp480_unsafe_from("e8a1e6285c4061a07c584136417db3e867cf77b12288380e518dab8538228e96abad778e1fe576deff39e638e030933cb8fa5c388fa8b06991ea6332"),
// 2673768771775032355420306564841108930438651217980189126243896874678717443069132673614464990588309533043439946857284622768054880686771881306409642
elem2: fp480_unsafe_from("db4365e116bcb8a9f1cd16c16f659be8441624488f0fa10cee176e6219c78cda3a75041e41eb847603b2eabe65b2f31867cbfc784f453487387ecaaa")
},
y: Fp2Elem {
// 3080607037190881313834826417530769563132997895310223092587326825944478280552006660025218522727539672756392754158719384720663526682905220416822282
elem1: fp480_unsafe_from("fca04d212ab8b13be77f82635c3ce496f0b3c0611aaf492f47067a062d754a28d442b701cb48a06809ffce876bb536c6b1371107e314f92a160c5c0a"),
// 2906149584369018327289172171212098825323249826660713579814103802892067659387776431613853400363371122569649698984076618174478076051599518261188038
elem2: fp480_unsafe_from("ee51da494993536a1fb297d54eb0c6804e8c6c6fd3d158900c9a421e276e058c620cf10104b27e945d8d124909a2a93fbda08b6ce6e072eeeafa15c6")
},
z: Fp2Elem {
//
elem1: Zero::zero(),
//
elem2: One::one()
}
}.map(&|fp| fp.to_monty()),
// Used to hash integers to a point in FP2
// Generated by multiplying g1 by the SHA256 hash of the date/time "Mon Mar 26 13:33:43 MDT 2018\n",
// encoded in ASCII/UTF-8, converted to a BigInt.
hash_element: TwistedHPoint {
x: Fp2Elem {
// 2755895806273995492284787079187941247738254659153318682910850469784894541505170101984499629579667341065183727568252238059654392233777140703184622
elem1: fp480_unsafe_from("e1ff8546060eb7ea879ff685d3f32a39f8e13a3315a48563eb407ccb14d92272f00ba5071e8ec873c585524a6f79bb14025b61046d2371c3fd1846ee"),
// 630223019374291956078632635377008181978279936792489208439110695275442238629433173084638817027401619964084048824893758705005177091915333122454106
elem2: fp480_unsafe_from("33ae8021a5b3f7d0bf99611976f6bd542e6a391b5af42d778ea5265b1f0d9098f4d74578be80932d1e6ac4efe7c7237e7da8a2ad49e0e9a6d270f25a")
},
y: Fp2Elem {
// 659567418809487070027824196603118281636508923398279856378657485535700744304348227321440219246561941778839111505653577989859933696546799454574627
elem1: fp480_unsafe_from("361689c368efd496748a650f060d7033574872c85e9ecc10b12bf923687d147efe21ee3c93d94c2dadafc4e2b563b32c42e77832766b434fde40d823"),
// 2632696014493840722302529499863944843283552594579584896121087553911353425460849587377878627157950485322470437984154786925535244302963434645693127
elem2: fp480_unsafe_from("d7e52485fdd198506e27b1dd34610a84e0555ece060067051768485e849e1a2710f2be426e1c7916ec14669844c0c37beddc834876d91facd6ad22c7")
},
z: Fp2Elem {
// 2723878025330396352455760809227014699447653800671598495327573996671655085492645713095099955627015617726770647513458138760772123814185152132721554
elem1: fp480_unsafe_from("df5f5c15c4df23c5f1135907a581cc838e3689435f18d610a30d378e8fd1c190245edb38dc5644a7907a10566dd28075de3db675bb875ef555d0ab92"),
// 2520811096583992837832885181589663735998061148584558864774875442611283633943850563303274829680791759077833709816521531207043963496532513260928366
elem2: fp480_unsafe_from("ceb84d4f5892e3ba709eb41979576c04d7897ce6dc763e867cfe34deecacde57d435ca92c15ecbecebf12c316746b8022da2c4df6ec685a261657d6e")
}
}.map(&|fp| fp.to_monty())
};
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn generator_times_2() {
//37777967648492203239675772600961898148040325589588086812374811831221462604944
let fp256 =
fp256_unsafe_from("5385926b9f6135086d1912901e5a433ffcebc19a30fadbd0ee8cee26ba719c90");
let result = FP_256_CURVE_POINTS.generator * fp256.to_monty();
let expected_result = HomogeneousPoint::new(
//56377452267431283559088187378398270325210563762492926393848580098576649271541
fp256_unsafe_from("7ca481d71abbae43395152eb7baa230d60543d43e2e8f89a18d182ecf8c3b8f5")
.to_monty(),
//46643694276241842996939080253335644316475473619096522181405937227991761798154
fp256_unsafe_from("671f653900901fc3688542e5939ba6c064a7768f34fe45492a49e1f6d4d7c40a")
.to_monty(),
);
assert_eq!(result, expected_result)
}
}