-
Notifications
You must be signed in to change notification settings - Fork 8
/
tests.rs
231 lines (202 loc) · 7.09 KB
/
tests.rs
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
use crate::{self as sum_storage, Config};
use frame_support::dispatch::{DispatchError, DispatchErrorWithPostInfo, PostDispatchInfo};
use frame_support::{assert_ok, construct_runtime, parameter_types};
// Import `plonk_pallet` and dependency
pub use plonk_pallet::*;
use rand_core::SeedableRng;
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
};
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<TestRuntime>;
type Block = frame_system::mocking::MockBlock<TestRuntime>;
construct_runtime!(
pub enum TestRuntime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Module, Call, Config, Storage, Event<T>},
// Define the `plonk_pallet` in `contruct_runtime`
Plonk: plonk_pallet::{Module, Call, Storage, Event<T>},
SumStorage: sum_storage::{Module, Call, Storage, Event<T>},
}
);
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub BlockWeights: frame_system::limits::BlockWeights =
frame_system::limits::BlockWeights::simple_max(1024);
}
impl frame_system::Config for TestRuntime {
type BaseCallFilter = ();
type BlockWeights = ();
type BlockLength = ();
type Origin = Origin;
type Index = u64;
type Call = Call;
type BlockNumber = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = Event;
type BlockHashCount = BlockHashCount;
type DbWeight = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
}
// Implement a circuit that checks:
// 1) a + b = c where C is a PI
// 2) a <= 2^6
// 3) b <= 2^5
// 4) a * b = d where D is a PI
// 5) JubJub::GENERATOR * e(JubJubScalar) = f where F is a Public Input
#[derive(Debug, Default)]
pub struct TestCircuit {
pub a: BlsScalar,
pub b: BlsScalar,
pub c: BlsScalar,
pub d: BlsScalar,
pub e: JubJubScalar,
pub f: JubJubAffine,
}
impl Circuit for TestCircuit {
const CIRCUIT_ID: [u8; 32] = [0xff; 32];
fn gadget(&mut self, composer: &mut TurboComposer) -> Result<(), PlonkError> {
let a = composer.append_witness(self.a);
let b = composer.append_witness(self.b);
// Make first constraint a + b = c
let constraint = Constraint::new().left(1).right(1).public(-self.c).a(a).b(b);
composer.append_gate(constraint);
// Check that a and b are in range
composer.component_range(a, 1 << 6);
composer.component_range(b, 1 << 5);
// Make second constraint a * b = d
let constraint = Constraint::new()
.mult(1)
.output(1)
.public(-self.d)
.a(a)
.b(b);
composer.append_gate(constraint);
let e = composer.append_witness(self.e);
let scalar_mul_result = composer.component_mul_generator(e, GENERATOR_EXTENDED);
composer.assert_equal_public_point(scalar_mul_result, self.f);
Ok(())
}
fn public_inputs(&self) -> Vec<PublicInputValue> {
vec![self.c.into(), self.d.into(), self.f.into()]
}
fn padded_gates(&self) -> usize {
1 << 11
}
}
impl plonk_pallet::Config for TestRuntime {
type CustomCircuit = TestCircuit;
type Event = Event;
}
impl Config for TestRuntime {
type Event = Event;
}
// This function basically just builds a genesis storage key/value store according to
// our desired mockup.
fn new_test_ext() -> sp_io::TestExternalities {
frame_system::GenesisConfig::default()
.build_storage::<TestRuntime>()
.unwrap()
.into()
}
#[test]
fn default_sum_zero() {
new_test_ext().execute_with(|| {
assert_eq!(SumStorage::get_sum(), 0);
});
}
/// The trusted setup test Ok and Err
#[test]
fn trusted_setup() {
new_test_ext().execute_with(|| {
let rng = get_rng();
assert_ok!(Plonk::trusted_setup(Origin::signed(1), 12, rng));
let rng = get_rng();
assert_eq!(
Plonk::trusted_setup(Origin::signed(1), 12, rng),
Err(DispatchErrorWithPostInfo {
post_info: PostDispatchInfo::from(()),
error: DispatchError::Other("already setup"),
})
);
})
}
/// The set `Thing1` storage with valid proof
#[test]
fn sums_thing_one_with_valid_proof() {
new_test_ext().execute_with(|| {
let rng = get_rng();
assert_ok!(Plonk::trusted_setup(Origin::signed(1), 12, rng));
let pp = Plonk::public_parameter().unwrap();
let mut circuit = TestCircuit::default();
let (pk, vd) = circuit.compile(&pp).unwrap();
let proof = {
let mut circuit = TestCircuit {
a: BlsScalar::from(20u64),
b: BlsScalar::from(5u64),
c: BlsScalar::from(25u64),
d: BlsScalar::from(100u64),
e: JubJubScalar::from(2u64),
f: JubJubAffine::from(GENERATOR_EXTENDED * JubJubScalar::from(2u64)),
};
circuit.prove(&pp, &pk, b"Test").unwrap()
};
let public_inputs: Vec<PublicInputValue> = vec![
BlsScalar::from(25u64).into(),
BlsScalar::from(100u64).into(),
JubJubAffine::from(GENERATOR_EXTENDED * JubJubScalar::from(2u64)).into(),
];
assert_ok!(SumStorage::set_thing_1(Origin::signed(1), 42, vd, proof, public_inputs, Transcript(b"Test")));
assert_eq!(SumStorage::get_sum(), 42);
});
}
/// The set `Thing1` storage with invalid proof
#[test]
fn sums_thing_one_with_invalid_proof() {
new_test_ext().execute_with(|| {
let rng = get_rng();
assert_ok!(Plonk::trusted_setup(Origin::signed(1), 12, rng));
let pp = Plonk::public_parameter().unwrap();
let mut circuit = TestCircuit::default();
let (pk, vd) = circuit.compile(&pp).unwrap();
let proof = {
let mut circuit = TestCircuit {
a: BlsScalar::from(20u64),
b: BlsScalar::from(5u64),
c: BlsScalar::from(25u64),
d: BlsScalar::from(100u64),
e: JubJubScalar::from(2u64),
f: JubJubAffine::from(GENERATOR_EXTENDED * JubJubScalar::from(2u64)),
};
circuit.prove(&pp, &pk, b"Test").unwrap()
};
let public_inputs: Vec<PublicInputValue> = vec![
// Change the value
BlsScalar::from(24u64).into(),
BlsScalar::from(100u64).into(),
JubJubAffine::from(GENERATOR_EXTENDED * JubJubScalar::from(2u64)).into(),
];
assert!(SumStorage::set_thing_1(Origin::signed(1), 42, vd, proof, public_inputs, Transcript(b"Test")).is_err());
assert_eq!(SumStorage::get_sum(), 0);
});
}
fn get_rng() -> FullcodecRng {
FullcodecRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
])
}