4
4
use core:: ops:: Neg ;
5
5
extern crate alloc;
6
6
7
+ use hex_literal:: hex;
7
8
use openvm:: io:: read_vec;
8
9
use openvm_ecc_guest:: {
9
10
algebra:: { Field , IntMod } ,
@@ -15,17 +16,24 @@ use openvm_ecc_guest::{
15
16
openvm:: entry!( main) ;
16
17
17
18
openvm_algebra_moduli_macros:: moduli_declare! {
19
+ // a prime that is 5 mod 8
20
+ Fp5mod8 { modulus = "115792089237316195423570985008687907853269984665640564039457584007913129639501" } ,
18
21
// a prime that is 1 mod 4
19
- Fp { modulus = "115792089237316195423570985008687907853269984665640564039457584007913129639501 " } ,
22
+ Fp1mod4 { modulus = "0xffffffffffffffffffffffffffffffff000000000000000000000001 " } ,
20
23
}
21
24
22
25
openvm_algebra_moduli_macros:: moduli_init! {
23
26
"0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F" ,
24
27
"0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" ,
25
28
"115792089237316195423570985008687907853269984665640564039457584007913129639501" ,
29
+ "1000000007" ,
30
+ "0xffffffffffffffffffffffffffffffff000000000000000000000001" ,
31
+ "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
26
32
}
27
33
28
- impl Field for Fp {
34
+ const CURVE_B_5MOD8 : Fp5mod8 = Fp5mod8 :: from_const_u8 ( 3 ) ;
35
+
36
+ impl Field for Fp5mod8 {
29
37
const ZERO : Self = <Self as IntMod >:: ZERO ;
30
38
const ONE : Self = <Self as IntMod >:: ONE ;
31
39
@@ -40,24 +48,51 @@ impl Field for Fp {
40
48
}
41
49
}
42
50
43
- const MY_CURVE_B : Fp = Fp :: from_const_u8 ( 3 ) ;
51
+ const CURVE_A_1MOD4 : Fp1mod4 = Fp1mod4 :: from_const_bytes ( hex ! (
52
+ "FEFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000"
53
+ ) ) ;
54
+ const CURVE_B_1MOD4 : Fp1mod4 = Fp1mod4 :: from_const_bytes ( hex ! (
55
+ "B4FF552343390B27BAD8BFD7B7B04450563241F5ABB3040C850A05B400000000"
56
+ ) ) ;
44
57
45
- openvm_ecc_sw_macros:: sw_declare! {
46
- MyCurvePoint {
47
- mod_type = Fp ,
48
- b = MY_CURVE_B ,
58
+ impl Field for Fp1mod4 {
59
+ const ZERO : Self = <Self as IntMod >:: ZERO ;
60
+ const ONE : Self = <Self as IntMod >:: ONE ;
61
+
62
+ type SelfRef < ' a > = & ' a Self ;
63
+
64
+ fn double_assign ( & mut self ) {
65
+ IntMod :: double_assign ( self ) ;
49
66
}
67
+
68
+ fn square_assign ( & mut self ) {
69
+ IntMod :: square_assign ( self ) ;
70
+ }
71
+ }
72
+
73
+ openvm_ecc_sw_macros:: sw_declare! {
74
+ CurvePoint5mod8 {
75
+ mod_type = Fp5mod8 ,
76
+ b = CURVE_B_5MOD8 ,
77
+ } ,
78
+ CurvePoint1mod4 {
79
+ mod_type = Fp1mod4 ,
80
+ a = CURVE_A_1MOD4 ,
81
+ b = CURVE_B_1MOD4 ,
82
+ } ,
50
83
}
51
84
52
85
openvm_ecc_sw_macros:: sw_init! {
53
86
Secp256k1Point ,
54
- MyCurvePoint ,
87
+ CurvePoint5mod8 ,
88
+ CurvePoint1mod4 ,
55
89
}
56
90
57
91
// test decompression under an honest host
58
92
pub fn main ( ) {
59
93
setup_0 ( ) ;
60
94
setup_2 ( ) ;
95
+ setup_4 ( ) ;
61
96
setup_all_curves ( ) ;
62
97
63
98
let bytes = read_vec ( ) ;
@@ -69,13 +104,21 @@ pub fn main() {
69
104
// x = 5 is not on the x-coordinate of any point on the Secp256k1 curve
70
105
test_impossible_decompression_secp256k1 ( & Secp256k1Coord :: from_u8 ( 5 ) , rec_id) ;
71
106
72
- let x = Fp :: from_le_bytes ( & bytes[ 64 ..96 ] ) ;
73
- let y = Fp :: from_le_bytes ( & bytes[ 96 ..128 ] ) ;
107
+ let x = Fp5mod8 :: from_le_bytes ( & bytes[ 64 ..96 ] ) ;
108
+ let y = Fp5mod8 :: from_le_bytes ( & bytes[ 96 ..128 ] ) ;
74
109
let rec_id = y. as_le_bytes ( ) [ 0 ] & 1 ;
75
110
76
- test_possible_decompression :: < MyCurvePoint > ( & x, & y, rec_id) ;
77
- // x = 3 is not on the x-coordinate of any point on the MyCurve curve
78
- test_impossible_decompression_mycurve ( & Fp :: from_u8 ( 3 ) , rec_id) ;
111
+ test_possible_decompression :: < CurvePoint5mod8 > ( & x, & y, rec_id) ;
112
+ // x = 3 is not on the x-coordinate of any point on the CurvePoint5mod8 curve
113
+ test_impossible_decompression_curvepoint5mod8 ( & Fp5mod8 :: from_u8 ( 3 ) , rec_id) ;
114
+
115
+ let x = Fp1mod4 :: from_le_bytes ( & bytes[ 128 ..160 ] ) ;
116
+ let y = Fp1mod4 :: from_le_bytes ( & bytes[ 160 ..192 ] ) ;
117
+ let rec_id = y. as_le_bytes ( ) [ 0 ] & 1 ;
118
+
119
+ test_possible_decompression :: < CurvePoint1mod4 > ( & x, & y, rec_id) ;
120
+ // x = 1 is not on the x-coordinate of any point on the CurvePoint1mod4 curve
121
+ test_impossible_decompression_curvepoint1mod4 ( & Fp1mod4 :: from_u8 ( 1 ) , rec_id) ;
79
122
}
80
123
81
124
fn test_possible_decompression < P : WeierstrassPoint + FromCompressed < P :: Coordinate > > (
@@ -98,18 +141,18 @@ fn test_possible_decompression<P: WeierstrassPoint + FromCompressed<P::Coordinat
98
141
// The test_impossible_decompression_* functions cannot be combined into a single function with a const generic parameter
99
142
// since the get_non_qr() function is not part of the WeierstrassPoint trait.
100
143
101
- fn test_impossible_decompression_mycurve ( x : & Fp , rec_id : u8 ) {
102
- let hint = MyCurvePoint :: hint_decompress ( x, & rec_id) . expect ( "hint should be well-formed" ) ;
144
+ fn test_impossible_decompression_curvepoint5mod8 ( x : & Fp5mod8 , rec_id : u8 ) {
145
+ let hint = CurvePoint5mod8 :: hint_decompress ( x, & rec_id) . expect ( "hint should be well-formed" ) ;
103
146
if hint. possible {
104
147
panic ! ( "decompression should be impossible" ) ;
105
148
} else {
106
149
let rhs = x * x * x
107
- + x * & <MyCurvePoint as WeierstrassPoint >:: CURVE_A
108
- + & <MyCurvePoint as WeierstrassPoint >:: CURVE_B ;
109
- assert_eq ! ( & hint. sqrt * & hint. sqrt, rhs * MyCurvePoint :: get_non_qr( ) ) ;
150
+ + x * & <CurvePoint5mod8 as WeierstrassPoint >:: CURVE_A
151
+ + & <CurvePoint5mod8 as WeierstrassPoint >:: CURVE_B ;
152
+ assert_eq ! ( & hint. sqrt * & hint. sqrt, rhs * CurvePoint5mod8 :: get_non_qr( ) ) ;
110
153
}
111
154
112
- let p = MyCurvePoint :: decompress ( x. clone ( ) , & rec_id) ;
155
+ let p = CurvePoint5mod8 :: decompress ( x. clone ( ) , & rec_id) ;
113
156
assert ! ( p. is_none( ) ) ;
114
157
}
115
158
@@ -127,3 +170,18 @@ fn test_impossible_decompression_secp256k1(x: &Secp256k1Coord, rec_id: u8) {
127
170
let p = Secp256k1Point :: decompress ( x. clone ( ) , & rec_id) ;
128
171
assert ! ( p. is_none( ) ) ;
129
172
}
173
+
174
+ fn test_impossible_decompression_curvepoint1mod4 ( x : & Fp1mod4 , rec_id : u8 ) {
175
+ let hint = CurvePoint1mod4 :: hint_decompress ( x, & rec_id) . expect ( "hint should be well-formed" ) ;
176
+ if hint. possible {
177
+ panic ! ( "decompression should be impossible" ) ;
178
+ } else {
179
+ let rhs = x * x * x
180
+ + x * & <CurvePoint1mod4 as WeierstrassPoint >:: CURVE_A
181
+ + & <CurvePoint1mod4 as WeierstrassPoint >:: CURVE_B ;
182
+ assert_eq ! ( & hint. sqrt * & hint. sqrt, rhs * CurvePoint1mod4 :: get_non_qr( ) ) ;
183
+ }
184
+
185
+ let p = CurvePoint1mod4 :: decompress ( x. clone ( ) , & rec_id) ;
186
+ assert ! ( p. is_none( ) ) ;
187
+ }
0 commit comments