Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion crates/iota-framework-snapshot/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
]
},
"5": {
"git_revision": "f2d8de9503f1",
"git_revision": "9aa26f09a38e",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ module iota::groth16 {
// Error if the given curve is not supported
const EInvalidCurve: u64 = 1;

#[allow(unused_const)]
// Error if the number of public inputs given exceeds the max.
const ETooManyPublicInputs: u64 = 2;

// Error if a public input does not have the correct length.
const EInvalidScalar: u64 = 3;

// We need to set an upper bound on the number of public inputs to avoid a DoS attack.
const MaxPublicInputs: u64 = 8; // This must match the corresponding constant in the native verify function.

/// Represents an elliptic curve construction to be used in the verifier. Currently we support BLS12-381 and BN254.
/// This should be given as the first parameter to `prepare_verifying_key` or `verify_groth16_proof`.
public struct Curve has store, copy, drop {
Expand Down Expand Up @@ -62,7 +67,11 @@ module iota::groth16 {
}

/// Creates a `PublicProofInputs` wrapper from bytes.
/// Creates a `PublicProofInputs` wrapper from bytes. The `bytes` parameter should be a concatenation of a number of
/// 32 bytes scalar field elements to be used as public inputs in little-endian format to a circuit.
public fun public_proof_inputs_from_bytes(bytes: vector<u8>): PublicProofInputs {
assert!(bytes.length() % 32 == 0, EInvalidScalar);
assert!(bytes.length() / 32 <= MaxPublicInputs, ETooManyPublicInputs);
PublicProofInputs { bytes }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ module iota::groth16_tests {
assert!(vk_bytes == expected_vk_bytes);
}

#[test]
#[expected_failure(abort_code = groth16::EInvalidScalar)]
fun test_invalid_public_inputs() {
let public_inputs_too_short = vector[x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849", x"1234"].flatten();
groth16::public_proof_inputs_from_bytes(public_inputs_too_short);
}

#[test]
#[expected_failure(abort_code = groth16::EInvalidVerifyingKey)]
fun test_prepare_verifying_key_invalid_bls12381() {
Expand Down Expand Up @@ -61,33 +68,27 @@ module iota::groth16_tests {
let invalid_pvk = groth16::pvk_from_bytes(vk_bytes, alpha_bytes, gamma_bytes, delta_bytes);
assert!(groth16::verify_groth16_proof(&curve, &invalid_pvk, &inputs, &proof) == false);

// Invalid public inputs bytes.
let invalid_inputs = groth16::public_proof_inputs_from_bytes(x"cf");
assert!(groth16::verify_groth16_proof(&curve, &pvk, &invalid_inputs, &proof) == false);

// Invalid proof bytes.
let invalid_proof = groth16::proof_points_from_bytes(x"4a");
assert!(groth16::verify_groth16_proof(&curve, &pvk, &inputs, &invalid_proof) == false);
}

#[test]
#[expected_failure(abort_code = groth16::ETooManyPublicInputs)]
fun test_too_many_public_inputs_bls12381() {
let curve = bls12381();

let vk_bytes = x"ada3c24e8c2e63579cc03fd1f112a093a17fc8ab0ff6eee7e04cab7bf8e03e7645381f309ec113309e05ac404c77ac7c8585d5e4328594f5a70a81f6bd4f29073883ee18fd90e2aa45d0fc7376e81e2fdf5351200386f5732e58eb6ff4d318dc";
let alpha_bytes = x"8b0f85a9e7d929244b0af9a35af10717bd667b6227aae37a6d336e815fb0d850873e0d87968345a493b2d31aa8aa400d9820af1d35fa862d1b339ea1f98ac70db7faa304bff120a151a1741d782d08b8f1c1080d4d2f3ebee63ac6cadc666605be306de0973be38fbbf0f54b476bbb002a74ff9506a2b9b9a34b99bfa7481a84a2c9face7065c19d7069cc5738c5350b886a5eeebe656499d2ffb360afc7aff20fa9ee689fb8b46863e90c85224e8f597bf323ad4efb02ee96eb40221fc89918a2c740eabd2886476c7f247a3eb34f0106b3b51cf040e2cdcafea68b0d8eecabf58b5aa2ece3d86259cf2dfa3efab1170c6eb11948826def533849b68335d76d60f3e16bb5c629b1c24df2bdd1a7f13c754d7fe38617ecd7783504e4615e5c13168185cc08de8d63a0f7032ab7e82ff78cf0bc46a84c98f2d95bb5af355cbbe525c44d5c1549c169dfe119a219dbf9038ec73729d187bd0e3ed369e4a2ec2be837f3dcfd958aea7110627d2c0192d262f17e722509c17196005b646a556cf010ef9bd2a2a9b937516a5ecdee516e77d14278e96bc891b630fc833dda714343554ae127c49460416430b7d4f048d08618058335dec0728ad37d10dd9d859c385a38673e71cc98e8439da0accc29de5c92d3c3dc98e199361e9f7558e8b0a2a315ccc5a72f54551f07fad6f6f4615af498aba98aea01a13a4eb84667fd87ee9782b1d812a03f8814f042823a7701238d0fec1e7dec2a26ffea00330b5c7930e95138381435d2a59f51313a48624e30b0a685e357874d41a0a19d83f7420c1d9c04";
let gamma_bytes = x"b675d1ff988116d1f2965d3c0c373569b74d0a1762ea7c4f4635faa5b5a8fa198a2a2ce6153f390a658dc9ad01a415491747e9de7d5f493f59cf05a52eb46eaac397ffc47aef1396cf0d8b75d0664077ea328ad6b63284b42972a8f11c523a60";
let delta_bytes = x"8229cb9443ef1fb72887f917f500e2aef998717d91857bcb92061ecd74d1d24c2b2b282736e8074e4316939b4c9853c117aa08ed49206860d648818b2cccb526585f5790161b1730d39c73603b482424a27bba891aaa6d99f3025d3df2a6bd42";
let pvk = groth16::pvk_from_bytes(vk_bytes, alpha_bytes, gamma_bytes, delta_bytes);

let inputs_bytes = x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849";
let inputs = groth16::public_proof_inputs_from_bytes(inputs_bytes);

let proof_bytes = x"a29981304df8e0f50750b558d4de59dbc8329634b81c986e28e9fff2b0faa52333b14a1f7b275b029e13499d1f5dd8ab955cf5fa3000a097920180381a238ce12df52207597eade4a365a6872c0a19a39c08a9bfb98b69a15615f90cc32660180ca32e565c01a49b505dd277713b1eae834df49643291a3601b11f56957bde02d5446406d0e4745d1bd32c8ccb8d8e80b877712f5f373016d2ecdeebb58caebc7a425b8137ebb1bd0c5b81c1d48151b25f0f24fe9602ba4e403811fb17db6f14";
let proof = groth16::proof_points_from_bytes(proof_bytes);

groth16::verify_groth16_proof(&curve, &pvk, &inputs, &proof);
fun test_too_many_public_inputs() {
// We give 9 inputs which exceeds the limit of 8
let inputs_bytes = vector[
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849",
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849",
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849",
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849",
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849",
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849",
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849",
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849",
x"440758042e68b76a376f2fecf3a5a8105edb194c3e774e5a760140305aec8849"
].flatten();
groth16::public_proof_inputs_from_bytes(inputs_bytes);
}

#[test]
Expand Down Expand Up @@ -120,6 +121,13 @@ module iota::groth16_tests {
groth16::prepare_verifying_key(&bn254(), &invalid_vk);
}

#[test]
#[expected_failure(abort_code = groth16::EInvalidScalar)]
fun test_invalid_public_inputs_bn254() {
let public_inputs_too_short = vector[x"3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a", x"1234"].flatten();
groth16::public_proof_inputs_from_bytes(public_inputs_too_short);
}

#[test]
fun test_verify_groth_16_proof_bn254() {
let curve = bn254();
Expand All @@ -144,33 +152,8 @@ module iota::groth16_tests {
let invalid_pvk = groth16::pvk_from_bytes(vk_bytes, alpha_bytes, gamma_bytes, delta_bytes);
assert!(groth16::verify_groth16_proof(&curve, &invalid_pvk, &inputs, &proof) == false);

// Invalid public inputs bytes.
let invalid_inputs = groth16::public_proof_inputs_from_bytes(x"cf");
assert!(groth16::verify_groth16_proof(&curve, &pvk, &invalid_inputs, &proof) == false);

// Invalid proof bytes.
let invalid_proof = groth16::proof_points_from_bytes(x"4a");
assert!(groth16::verify_groth16_proof(&curve, &pvk, &inputs, &invalid_proof) == false);
}

#[test]
#[expected_failure(abort_code = groth16::ETooManyPublicInputs)]
fun test_too_many_public_inputs_bn254() {
let curve = bn254();

let vk_bytes = x"e8324a3242be5193eb38cca8761691ce061e89ce86f1fce8fd7ef40808f12da3c67d9ed5667c841f956e11adbbe240ddf37a1e3a4a890600dc88f608b897898e";
let alpha_bytes = x"51e6d72cd3b0914dd232653f84e7971d3e5bbcde6b47ff8d6c05277e579f1c1eb2fe30aa252c63950de6ea00dd21a1027f6d130357e47c31fafeca0d31e19406231df42bc11ce376f8cf75135d9074f081c242c31f198d151ec69ec37d67cc2b12542cb306a7823c8b194f13672176c6ee8266b2a0c9f57a5dbdb2278046b511d44e715a3ebe02ec2e1cf493c1b1ada84676e234134a6da5a552f61d4e905e15c0dc58a3414d74304775de5ba8571128f3548d269b51fdc08d5b646fd9157e0a2bc0c4bec5a9a6048d17d1d6cd941b4d459f1de0c7c1d417f33995d2a8dd670b91f0baaccaaf2802100901711885026a5ec97fbbb801000d0d01185651947c1900e336921d07eb16d0e25a2192829540ad5eeb1c498ba9c6316e16807a55dc2b9a7f3dea2e4a2f485ed1295a96d6ca86851842b3a22f83507f93ac66a1dc341d5d22f592527d8ea5c12db16bbabe24b76b3e1baf825c8dcf147be369fd8c5300fd77d0aa8dce730e4e7442c93c4890023f3a266c9fbc90ebbf72825e798c4c00";
let gamma_bytes = x"240a80664919b9f7490209cff12bfd81c32c272607dc004661c792082cbe282ef826f56a3822ebd72345f86c7ee9872e23f10d1f2dbf43f8aca5dc2ceb5388a5";
let delta_bytes = x"f755df8c90edab48ac5adafef6a5a461902217f392e3aa4c34c0462b700c18164f79018778755980d491647de11ecc51fda2cc17171c4b44485ec37ccd23a69b";
let pvk = groth16::pvk_from_bytes(vk_bytes, alpha_bytes, gamma_bytes, delta_bytes);

// We give 9 equal inputs which exceeds the limit of 8
let inputs_bytes = x"3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a3fd7c445c6845a9399d1a7b8394c16373399a037786c169f16219359d3be840a";
let inputs = groth16::public_proof_inputs_from_bytes(inputs_bytes);

let proof_bytes = x"dd2ef02e57d6a282df6b7f36c134ab7e55c2e04c5b8cbd7831be18e0e7224623ae8bd6c41637c10cbd02f5e68de6394461f417895ddd264d6f0ddacf68c6cd02feb8881f0efa599139a6faf4223dd8743777c4346cba52322eb466af96f2be9f813af1450f84d6f8029804f60cac1add70ad1a3d4226404f84f4022dc18caa0f";
let proof = groth16::proof_points_from_bytes(proof_bytes);

groth16::verify_groth16_proof(&curve, &pvk, &inputs, &proof);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,13 @@ module std::vector {
acc
}

/// Concatenate the vectors of `v` into a single vector, keeping the order of the elements.
public fun flatten<T>(v: vector<vector<T>>): vector<T> {
let mut r = vector[];
v.do!(|u| r.append(u));
r
}

/// Whether any element in the vector `v` satisfies the predicate `f`.
/// If the vector is empty, returns `false`.
public macro fun any<$T>($v: &vector<$T>, $f: |&$T| -> bool): bool {
Expand Down
10 changes: 10 additions & 0 deletions crates/iota-framework/packages/move-stdlib/tests/vector_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,16 @@ module std::vector_tests {
assert!(r.fold!(10, |acc, e| acc + e) == 16);
}

#[test]
fun test_flatten() {
assert!(vector<vector<u8>>[].flatten().is_empty());
assert!(vector<vector<u8>>[vector[], vector[]].flatten().is_empty());
assert!(vector[vector[1]].flatten() == vector[1]);
assert!(vector[vector[1], vector[]].flatten() == vector[1]);
assert!(vector[vector[1], vector[2]].flatten() == vector[1, 2]);
assert!(vector[vector[1], vector[2, 3]].flatten() == vector[1, 2, 3]);
}

#[test]
fun any_all_macro() {
assert!(vector<u8>[].any!(|e| *e == 2) == false);
Expand Down
Binary file modified crates/iota-framework/packages_compiled/iota-framework
Binary file not shown.
Binary file modified crates/iota-framework/packages_compiled/move-stdlib
Binary file not shown.
87 changes: 45 additions & 42 deletions crates/iota-framework/published_api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1018,48 +1018,6 @@ ecvrf_verify
ed25519_verify
public fun
0x2::ed25519
Curve
public struct
0x2::groth16
PreparedVerifyingKey
public struct
0x2::groth16
PublicProofInputs
public struct
0x2::groth16
ProofPoints
public struct
0x2::groth16
bls12381
public fun
0x2::groth16
bn254
public fun
0x2::groth16
pvk_from_bytes
public fun
0x2::groth16
pvk_to_bytes
public fun
0x2::groth16
public_proof_inputs_from_bytes
public fun
0x2::groth16
proof_points_from_bytes
public fun
0x2::groth16
prepare_verifying_key
public fun
0x2::groth16
prepare_verifying_key_internal
fun
0x2::groth16
verify_groth16_proof
public fun
0x2::groth16
verify_groth16_proof_internal
fun
0x2::groth16
blake2b256
public fun
0x2::hash
Expand Down Expand Up @@ -2359,6 +2317,48 @@ create_internal
add_internal
fun
0x2::display
Curve
public struct
0x2::groth16
PreparedVerifyingKey
public struct
0x2::groth16
PublicProofInputs
public struct
0x2::groth16
ProofPoints
public struct
0x2::groth16
bls12381
public fun
0x2::groth16
bn254
public fun
0x2::groth16
pvk_from_bytes
public fun
0x2::groth16
pvk_to_bytes
public fun
0x2::groth16
public_proof_inputs_from_bytes
public fun
0x2::groth16
proof_points_from_bytes
public fun
0x2::groth16
prepare_verifying_key
public fun
0x2::groth16
prepare_verifying_key_internal
fun
0x2::groth16
verify_groth16_proof
public fun
0x2::groth16
verify_groth16_proof_internal
fun
0x2::groth16
IOTA
public struct
0x2::iota
Expand Down Expand Up @@ -4021,6 +4021,9 @@ insert
swap_remove
public fun
0x1::vector
flatten
public fun
0x1::vector
Option
public struct
0x1::option
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ system_state_version: 1
iota_treasury_cap:
inner:
id:
id: "0x9bad1db98534e8ff8830e3e972d51de9d8e805cddd7b5fe068a82d28ab80edf2"
id: "0x57302c90e92c66fb217c7cb382c02c297029aa84ced3da93a6a3cb11f3779ef2"
total_supply:
value: "751500000000000000"
validators:
Expand Down Expand Up @@ -244,56 +244,56 @@ validators:
next_epoch_primary_address: ~
extra_fields:
id:
id: "0x654543304649cdb446d7520e4dc73e18ba7b0052d074461217bdb59a9a4b5004"
id: "0x42ac1f91940c6f6c6e411b4ca4ad89e104ce4b847a45a95a1e34158f098650c1"
size: 0
voting_power: 10000
operation_cap_id: "0x39842dafa635cc98937c706422cab369449880b60171133990ac523aeb354265"
operation_cap_id: "0x90ed310f6e9489126b7a300dea9920c7ad9fb66a7c16a45dcf27a2fc6e750cd8"
gas_price: 1000
staking_pool:
id: "0xfa1c34ca8498e47b6944c9264500dcae9a55aa0b35f8c1a4269020053e6b20f2"
id: "0xb9579834f32582b0251612553098bc11b83f343d337bd9daed119c46d28dd71c"
activation_epoch: 0
deactivation_epoch: ~
iota_balance: 1500000000000000
rewards_pool:
value: 0
pool_token_balance: 1500000000000000
exchange_rates:
id: "0xe603908e2421b9d3fdad586484b1e9866c5d454f39483c301f90e3646b630455"
id: "0xa0cb55e9ad9d72f8adea179c192eee5724596d92fb9c3864b3c4a3cdbbb68b0b"
size: 1
pending_stake: 0
pending_total_iota_withdraw: 0
pending_pool_token_withdraw: 0
extra_fields:
id:
id: "0x37b27997bf635223aca8c47b770de9f1ea735af76272adfe1d8f4ecccc9fdbd4"
id: "0x5abf9db947c1f40cd695996bb335c5eafbcf8bd2c937546bd022688d62002fcb"
size: 0
commission_rate: 200
next_epoch_stake: 1500000000000000
next_epoch_gas_price: 1000
next_epoch_commission_rate: 200
extra_fields:
id:
id: "0xb914c3349635a3a22d1de8afbcfac5105d384e36af2beb43ab351df769f22dd4"
id: "0x3af4ab099b4e26baa29dfee872649b1449109767083dbeda3b22021d08089b0b"
size: 0
pending_active_validators:
contents:
id: "0xcee700551c6ab3aaa41f471b92d1afa24eb584bd63b61b2a10547a6d6e249e96"
id: "0xb375b28fe345abeff33319322a65ec64ff478589c96b945e5e7a3d5a266d45c6"
size: 0
pending_removals: []
staking_pool_mappings:
id: "0x4514f84e2ac7bb233ce7006dff24ef73022a895719430eb7c841a8eecd5fcc05"
id: "0x42af0363c43a31de6302df3c031af3f1f6e563a03d58736516b60e6417f571cb"
size: 1
inactive_validators:
id: "0x865dc1e46f26593a104715f5f56c466313e31029bb4343b4ca029e2afc27ee1e"
id: "0x6485a6dac50c9be9d01aacab6c23e03d89400fb0a325a1b15a618a62f646b05b"
size: 0
validator_candidates:
id: "0x9dcd8321ee9b013f0f2284ca7bae722a1774c02614fa5adc4c5f60162795747c"
id: "0x3bd42bdd20893cb0290cf344191a6470cdfdaa27cd7c992bfaa850463aea8fb7"
size: 0
at_risk_validators:
contents: []
extra_fields:
id:
id: "0xa542e981092d96978d900d7ec50e9846dd281b63dc5f5f7574715fe108b3e727"
id: "0x7b94fe844817c52f155e78790e5c78eb37dd3a61886100067758d5bb4157eaac"
size: 0
storage_fund:
total_object_storage_rebates:
Expand All @@ -310,7 +310,7 @@ parameters:
validator_low_stake_grace_period: 7
extra_fields:
id:
id: "0xdb6fb066cdcbbcbca0b135709e19d0262ab2097f3e422acaf9dff82b3f224fae"
id: "0xd1dac0008158812022352e77aac8d5e061cd511c9df6484d36af4ab85c66f626"
size: 0
iota_system_admin_cap:
dummy_field: false
Expand All @@ -327,5 +327,5 @@ safe_mode_non_refundable_storage_fee: 0
epoch_start_timestamp_ms: 10
extra_fields:
id:
id: "0x9df4c13e52917f8305f1abcf31f438bfce6b0d642bde9f35f7b1d42fee8a93a0"
id: "0xf62bd0d080f416eb4ab61914c4b59a45d3a11383f46d00747ac5e34eed295e6e"
size: 0
Loading