|
| 1 | +use noir_bigcurve::curves::secp256k1::Secp256k1; |
| 2 | +use noir_bigcurve::curves::secp256k1::Secp256k1Scalar; |
| 3 | +use noir_bigcurve::scalar_field::ScalarFieldTrait; |
| 4 | +use noir_bigcurve::BigCurveTrait; |
| 5 | +use bignum::{Secp256k1_Fq, Secp256k1_Fr, BigNum}; |
| 6 | + |
| 7 | +// No 'pub' on these |
| 8 | +fn prove_discrete_log( |
| 9 | + g_x: Secp256k1_Fq, |
| 10 | + g_y: Secp256k1_Fq, |
| 11 | + k: Secp256k1_Fr, |
| 12 | + q_x: Secp256k1_Fq, |
| 13 | + q_y: Secp256k1_Fq, |
| 14 | +) { |
| 15 | + let G = Secp256k1 { x: g_x, y: g_y, is_infinity: false }; |
| 16 | + assert(!G.is_infinity); |
| 17 | + G.validate_on_curve(); |
| 18 | + |
| 19 | + let Q = Secp256k1 { x: q_x, y: q_y, is_infinity: false }; |
| 20 | + Q.validate_on_curve(); |
| 21 | + |
| 22 | + let k_scalar: Secp256k1Scalar = Secp256k1Scalar::from_bignum(k); |
| 23 | + let computed_Q = G.mul(k_scalar); |
| 24 | + |
| 25 | + assert(computed_Q.x == q_x); |
| 26 | + assert(computed_Q.y == q_y); |
| 27 | +} |
| 28 | + |
| 29 | +// Only 'pub' in main for public inputs |
| 30 | +pub fn main( |
| 31 | + g_x: pub Secp256k1_Fq, |
| 32 | + g_y: pub Secp256k1_Fq, |
| 33 | + k: Secp256k1_Fr, |
| 34 | + q_x: pub Secp256k1_Fq, |
| 35 | + q_y: pub Secp256k1_Fq, |
| 36 | +) { |
| 37 | + prove_discrete_log(g_x, g_y, k, q_x, q_y); |
| 38 | +} |
| 39 | +// Example test: Prove knowledge of k such that Q = kG |
| 40 | +#[test] |
| 41 | +fn test_prove_discrete_log() { |
| 42 | + let g_x = Secp256k1_Fq::from_limbs([809934545436666192144300149831112600, 532189659306663695932703699144214274, 31166]); |
| 43 | + let g_y = Secp256k1_Fq::from_limbs([123079417438355278731207347528586424, 1134337383257087261818981465599813885, 18490]); |
| 44 | + |
| 45 | + // Secret scalar k (witness) |
| 46 | + let k = Secp256k1_Fr::from_limbs([2,0,0]); |
| 47 | + |
| 48 | + // Public Q = k * G |
| 49 | + let q_x = Secp256k1_Fq::from_limbs([620769414058672675662360539292540645, 662428720985405666719129047941306460, 50692]); |
| 50 | + let q_y = Secp256k1_Fq::from_limbs([1278327165322711450801813382677652778, 545163776316525295403132726738087671, 6881]); |
| 51 | + |
| 52 | + prove_discrete_log(g_x, g_y, k, q_x, q_y); |
| 53 | +} |
| 54 | + |
| 55 | +#[test(should_fail)] |
| 56 | +fn test_prove_discrete_log_wrong_Q() { |
| 57 | + let g_x = Secp256k1_Fq::from_limbs([809934545436666192144300149831112600, 532189659306663695932703699144214274, 31166]); |
| 58 | + let g_y = Secp256k1_Fq::from_limbs([123079417438355278731207347528586424, 1134337383257087261818981465599813885, 18490]); |
| 59 | + |
| 60 | + let k = Secp256k1_Fr::from_limbs([2,0,0]); |
| 61 | + |
| 62 | + // Wrong Q |
| 63 | + let q_x = Secp256k1_Fq::from_limbs([258484535409603203050605737993582329, 716568843669635254349561846039718325, 63792]); |
| 64 | + let q_y = Secp256k1_Fq::from_limbs([3439865459799723184042666981123698, 638964607539318458049780617139410533, 14479]); |
| 65 | + |
| 66 | + prove_discrete_log(g_x, g_y, k, q_x, q_y); |
| 67 | +} |
| 68 | +#[test(should_fail)] |
| 69 | +fn test_prove_discrete_log_wrong_point() { |
| 70 | + // Deliberately choose a point NOT on secp256k1 |
| 71 | + let bad_x = Secp256k1_Fq::from_limbs([258484535409603203050605737993582330, 716568843669635254349561846039718325, 63792]); |
| 72 | + let bad_y = Secp256k1_Fq::from_limbs([3439865459799723184042666981123699, 638964607539318458049780617139410533, 14479]); |
| 73 | + let k = Secp256k1_Fr::from_limbs([2,0,0]); |
| 74 | + let q_x = Secp256k1_Fq::from_limbs([516969070819206406101211480282132933, 103909691554354635795316631799092074, 62049]); |
| 75 | + let q_y = Secp256k1_Fq::from_limbs([6879730919599446368085333962247398, 1277929215078636916099561234278821066, 28958]); |
| 76 | + |
| 77 | + prove_discrete_log(bad_x, bad_y, k, q_x, q_y); |
| 78 | +} |
0 commit comments