-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stdlib): Implement elliptic curve primitives (#964)
Implement elliptic curve primitives
- Loading branch information
Showing
8 changed files
with
1,626 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
name = "Baby Jubjub sanity checks" | ||
authors = [""] | ||
compiler_version = "0.1" | ||
|
||
[dependencies] |
211 changes: 211 additions & 0 deletions
211
crates/nargo/tests/test_data/ec_baby_jubjub/src/main.nr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
// Tests may be checked against https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/tree/main/poc | ||
|
||
use dep::std::ec::tecurve::affine::Curve as AffineCurve; | ||
use dep::std::ec::tecurve::affine::Point as Gaffine; | ||
use dep::std::ec::tecurve::curvegroup::Curve; | ||
use dep::std::ec::tecurve::curvegroup::Point as G; | ||
|
||
use dep::std::ec::swcurve::affine::Point as SWGaffine; | ||
use dep::std::ec::swcurve::curvegroup::Point as SWG; | ||
|
||
use dep::std::ec::montcurve::affine::Point as MGaffine; | ||
use dep::std::ec::montcurve::curvegroup::Point as MG; | ||
|
||
fn main() { | ||
// This test only makes sense if Field is the right prime field. | ||
if 21888242871839275222246405745257275088548364400416034343698204186575808495617 == 0 | ||
{ | ||
// Define Baby Jubjub (ERC-2494) parameters in affine representation | ||
let bjj_affine = AffineCurve::new(168700, 168696, Gaffine::new(995203441582195749578291179787384436505546430278305826713579947235728471134,5472060717959818805561601436314318772137091100104008585924551046643952123905)); | ||
|
||
// Test addition | ||
let p1_affine = Gaffine::new(17777552123799933955779906779655732241715742912184938656739573121738514868268, 2626589144620713026669568689430873010625803728049924121243784502389097019475); | ||
let p2_affine = Gaffine::new(16540640123574156134436876038791482806971768689494387082833631921987005038935, 20819045374670962167435360035096875258406992893633759881276124905556507972311); | ||
|
||
let p3_affine = bjj_affine.add(p1_affine, p2_affine); | ||
constrain p3_affine.eq(Gaffine::new(7916061937171219682591368294088513039687205273691143098332585753343424131937, | ||
14035240266687799601661095864649209771790948434046947201833777492504781204499)); | ||
|
||
// Test scalar multiplication | ||
let p4_affine = bjj_affine.mul(2, p1_affine); | ||
constrain p4_affine.eq(Gaffine::new(6890855772600357754907169075114257697580319025794532037257385534741338397365, | ||
4338620300185947561074059802482547481416142213883829469920100239455078257889)); | ||
constrain p4_affine.eq(bjj_affine.bit_mul([0,1], p1_affine)); | ||
|
||
// Test subtraction | ||
let p5_affine = bjj_affine.subtract(p3_affine, p3_affine); | ||
constrain p5_affine.eq(Gaffine::zero()); | ||
|
||
// Check that these points are on the curve | ||
constrain bjj_affine.contains(bjj_affine.gen) | ||
& bjj_affine.contains(p1_affine) | ||
& bjj_affine.contains(p2_affine) | ||
& bjj_affine.contains(p3_affine) | ||
& bjj_affine.contains(p4_affine) | ||
& bjj_affine.contains(p5_affine); | ||
|
||
// Test CurveGroup equivalents | ||
let bjj = bjj_affine.into_group(); // Baby Jubjub | ||
|
||
let p1 = p1_affine.into_group(); | ||
let p2 = p2_affine.into_group(); | ||
let p3 = p3_affine.into_group(); | ||
let p4 = p4_affine.into_group(); | ||
let p5 = p5_affine.into_group(); | ||
|
||
// Test addition | ||
constrain p3.eq(bjj.add(p1, p2)); | ||
|
||
// Test scalar multiplication | ||
constrain p4.eq(bjj.mul(2, p1)); | ||
constrain p4.eq(bjj.bit_mul([0,1], p1)); | ||
|
||
// Test subtraction | ||
constrain G::zero().eq(bjj.subtract(p3, p3)); | ||
constrain p5.eq(G::zero()); | ||
|
||
// Check that these points are on the curve | ||
constrain bjj.contains(bjj.gen) | ||
& bjj.contains(p1) | ||
& bjj.contains(p2) | ||
& bjj.contains(p3) | ||
& bjj.contains(p4) | ||
& bjj.contains(p5); | ||
|
||
// Test SWCurve equivalents of the above | ||
// First the affine representation | ||
let bjj_swcurve_affine = bjj_affine.into_swcurve(); | ||
|
||
let p1_swcurve_affine = bjj_affine.map_into_swcurve(p1_affine); | ||
let p2_swcurve_affine = bjj_affine.map_into_swcurve(p2_affine); | ||
let p3_swcurve_affine = bjj_affine.map_into_swcurve(p3_affine); | ||
let p4_swcurve_affine = bjj_affine.map_into_swcurve(p4_affine); | ||
let p5_swcurve_affine = bjj_affine.map_into_swcurve(p5_affine); | ||
|
||
// Addition | ||
constrain p3_swcurve_affine.eq( | ||
bjj_swcurve_affine.add( | ||
p1_swcurve_affine, | ||
p2_swcurve_affine)); | ||
|
||
// Doubling | ||
constrain p4_swcurve_affine.eq(bjj_swcurve_affine.mul(2, p1_swcurve_affine)); | ||
constrain p4_swcurve_affine.eq(bjj_swcurve_affine.bit_mul([0,1], p1_swcurve_affine)); | ||
|
||
// Subtraction | ||
constrain SWGaffine::zero().eq(bjj_swcurve_affine.subtract(p3_swcurve_affine, p3_swcurve_affine)); | ||
constrain p5_swcurve_affine.eq(SWGaffine::zero()); | ||
|
||
// Check that these points are on the curve | ||
constrain bjj_swcurve_affine.contains(bjj_swcurve_affine.gen) | ||
& bjj_swcurve_affine.contains(p1_swcurve_affine) | ||
& bjj_swcurve_affine.contains(p2_swcurve_affine) | ||
& bjj_swcurve_affine.contains(p3_swcurve_affine) | ||
& bjj_swcurve_affine.contains(p4_swcurve_affine) | ||
& bjj_swcurve_affine.contains(p5_swcurve_affine); | ||
|
||
// Then the CurveGroup representation | ||
let bjj_swcurve = bjj.into_swcurve(); | ||
|
||
let p1_swcurve = bjj.map_into_swcurve(p1); | ||
let p2_swcurve = bjj.map_into_swcurve(p2); | ||
let p3_swcurve = bjj.map_into_swcurve(p3); | ||
let p4_swcurve = bjj.map_into_swcurve(p4); | ||
let p5_swcurve = bjj.map_into_swcurve(p5); | ||
|
||
// Addition | ||
constrain p3_swcurve.eq( | ||
bjj_swcurve.add( | ||
p1_swcurve, | ||
p2_swcurve)); | ||
|
||
// Doubling | ||
constrain p4_swcurve.eq(bjj_swcurve.mul(2, p1_swcurve)); | ||
constrain p4_swcurve.eq(bjj_swcurve.bit_mul([0,1], p1_swcurve)); | ||
|
||
// Subtraction | ||
constrain SWG::zero().eq(bjj_swcurve.subtract(p3_swcurve, p3_swcurve)); | ||
constrain p5_swcurve.eq(SWG::zero()); | ||
|
||
// Check that these points are on the curve | ||
constrain bjj_swcurve.contains(bjj_swcurve.gen) | ||
& bjj_swcurve.contains(p1_swcurve) | ||
& bjj_swcurve.contains(p2_swcurve) | ||
& bjj_swcurve.contains(p3_swcurve) | ||
& bjj_swcurve.contains(p4_swcurve) | ||
& bjj_swcurve.contains(p5_swcurve); | ||
|
||
// Test MontCurve conversions | ||
// First the affine representation | ||
let bjj_montcurve_affine = bjj_affine.into_montcurve(); | ||
|
||
let p1_montcurve_affine = p1_affine.into_montcurve(); | ||
let p2_montcurve_affine = p2_affine.into_montcurve(); | ||
let p3_montcurve_affine = p3_affine.into_montcurve(); | ||
let p4_montcurve_affine = p4_affine.into_montcurve(); | ||
let p5_montcurve_affine = p5_affine.into_montcurve(); | ||
|
||
// Addition | ||
constrain p3_montcurve_affine.eq( | ||
bjj_montcurve_affine.add( | ||
p1_montcurve_affine, | ||
p2_montcurve_affine)); | ||
|
||
// Doubling | ||
constrain p4_montcurve_affine.eq(bjj_montcurve_affine.mul(2, p1_montcurve_affine)); | ||
constrain p4_montcurve_affine.eq(bjj_montcurve_affine.bit_mul([0,1], p1_montcurve_affine)); | ||
|
||
// Subtraction | ||
constrain MGaffine::zero().eq(bjj_montcurve_affine.subtract(p3_montcurve_affine, p3_montcurve_affine)); | ||
constrain p5_montcurve_affine.eq(MGaffine::zero()); | ||
|
||
// Check that these points are on the curve | ||
constrain bjj_montcurve_affine.contains(bjj_montcurve_affine.gen) | ||
& bjj_montcurve_affine.contains(p1_montcurve_affine) | ||
& bjj_montcurve_affine.contains(p2_montcurve_affine) | ||
& bjj_montcurve_affine.contains(p3_montcurve_affine) | ||
& bjj_montcurve_affine.contains(p4_montcurve_affine) | ||
& bjj_montcurve_affine.contains(p5_montcurve_affine); | ||
|
||
// Then the CurveGroup representation | ||
let bjj_montcurve = bjj.into_montcurve(); | ||
|
||
let p1_montcurve = p1_montcurve_affine.into_group(); | ||
let p2_montcurve = p2_montcurve_affine.into_group(); | ||
let p3_montcurve = p3_montcurve_affine.into_group(); | ||
let p4_montcurve = p4_montcurve_affine.into_group(); | ||
let p5_montcurve = p5_montcurve_affine.into_group(); | ||
|
||
// Addition | ||
constrain p3_montcurve.eq( | ||
bjj_montcurve.add( | ||
p1_montcurve, | ||
p2_montcurve)); | ||
|
||
// Doubling | ||
constrain p4_montcurve.eq(bjj_montcurve.mul(2, p1_montcurve)); | ||
constrain p4_montcurve.eq(bjj_montcurve.bit_mul([0,1], p1_montcurve)); | ||
|
||
// Subtraction | ||
constrain MG::zero().eq(bjj_montcurve.subtract(p3_montcurve, p3_montcurve)); | ||
constrain p5_montcurve.eq(MG::zero()); | ||
|
||
// Check that these points are on the curve | ||
constrain bjj_montcurve.contains(bjj_montcurve.gen) | ||
& bjj_montcurve.contains(p1_montcurve) | ||
& bjj_montcurve.contains(p2_montcurve) | ||
& bjj_montcurve.contains(p3_montcurve) | ||
& bjj_montcurve.contains(p4_montcurve) | ||
& bjj_montcurve.contains(p5_montcurve); | ||
|
||
// Elligator 2 map-to-curve | ||
let ell2_pt_map = bjj_affine.elligator2_map(27); | ||
|
||
constrain ell2_pt_map.eq(MGaffine::new(7972459279704486422145701269802978968072470631857513331988813812334797879121, 8142420778878030219043334189293412482212146646099536952861607542822144507872).into_tecurve()); | ||
|
||
// SWU map-to-curve | ||
let swu_pt_map = bjj_affine.swu_map(5,27); | ||
|
||
constrain swu_pt_map.eq(bjj_affine.map_from_swcurve(SWGaffine::new(2162719247815120009132293839392097468339661471129795280520343931405114293888, 5341392251743377373758788728206293080122949448990104760111875914082289313973))); | ||
} | ||
} |
Oops, something went wrong.