Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add remaining BLS wrapper proofs #70

Merged
merged 109 commits into from
Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
52db736
A stab at merging new changes in with main changes
Jul 30, 2021
3c062a1
Fix through bls_operations.saw
Aug 11, 2021
8384494
Fix min_key.saw
Aug 11, 2021
e5d6aaf
Re-integrate back into function_proofs
Aug 11, 2021
6cc3a07
CoreAggregateVerify Cryptol Spec
Aug 12, 2021
514a739
Add aggregate verify C functions and basic SAW spec
Aug 13, 2021
770423a
Works through signature checks
Aug 19, 2021
7136acd
Update header to more closely match code
Aug 19, 2021
972ea42
Partial keyvalidate precond setup
Aug 20, 2021
2e13038
Key validation and decompression
Aug 25, 2021
5fb2fde
Use explicit sizes on arrays
Aug 26, 2021
1afe744
Overrides for signature part
Aug 26, 2021
abda1b2
Satisfy POINTonE1_from_Jacobian precondition
Sep 3, 2021
4ff7fab
All preconds in blst_pairing_aggregate_pk_in_g2
Sep 3, 2021
0b1b742
Preconds through commit
Sep 8, 2021
f145139
Change blst.h final verify type to match aggregate.c
Sep 9, 2021
058a967
Get POINTonE1_from_Jacobian to apply
Sep 17, 2021
ea344ea
Works through miller loop, but slow with huge terms
Sep 17, 2021
ad8edd7
POINTonE1_from_Jacobian
Sep 22, 2021
b6c25ca
miller_loop
Sep 22, 2021
616fb56
conjugate_fp12
Sep 22, 2021
04a9dae
mul_fp12
Sep 22, 2021
9373e45
final_exp
Sep 23, 2021
fc94eae
vec_is_equal
Sep 23, 2021
2e1143b
vec_is_zero
Sep 24, 2021
3c9b118
Use finalverify ov
Sep 24, 2021
3ed8b9c
finalverify proof
Sep 25, 2021
d70edf0
Fix postcond
Sep 30, 2021
2b9048c
Figured out how to deal with map
Oct 2, 2021
5b4d7a0
Fix AggrSign union type
Oct 11, 2021
e58f3f9
Set N_MAX to 2
Oct 11, 2021
5039783
Start of aggregate proof for null_sig
Oct 21, 2021
f1ff25f
Through Hash_to_G1
Oct 21, 2021
d1d17b6
POINTonE1_from_Jacobian
Oct 21, 2021
957443c
Through vec_copies
Oct 21, 2021
a69fca1
Postcond on return and nelems
Oct 21, 2021
b8c6cf1
Complete code proof for nelems == 0
Oct 21, 2021
63eaa20
blst_pairing_aggregate_pk_in_g2_null_sig_1_first_commit
Oct 22, 2021
36e21df
Prove AggrSign is unchanged
Oct 22, 2021
0caefe7
All preconds for nth commit case
Oct 25, 2021
5d27fb2
Complete nth commit case proof
Oct 25, 2021
41f901d
All but AggrSign spec for non-null sig case
Oct 29, 2021
694c5c8
AggrSign postcond
Oct 29, 2021
112fe79
Fix up aggregate sig case so ov applies
Nov 3, 2021
ae4e89a
ov applies in first commit case
Nov 4, 2021
1fda13c
ov for n == 0 null sig case applies
Nov 4, 2021
4c4fc31
More rigorous accounting of ctx->GT and ctx->ctrl
Nov 10, 2021
6791c17
Restore `n` loop bound
Nov 10, 2021
bcfd8e8
Works with commit!
Nov 10, 2021
ab6e118
Some final goal work
Nov 11, 2021
4cb03f6
Theorems in place for an n=1 proof
Nov 16, 2021
1e57113
Relate finalverify to core_verify_pk_in_g2_impl
Nov 16, 2021
38466aa
Make it easy to simplify aggregate loop
Nov 16, 2021
1f554be
2/4 bls_ate_pairing args line up
Nov 16, 2021
c99b367
bls_ate_pairing for sig matches (3/4 matches now)
Nov 17, 2021
483cbf3
All bls_ate_pairing calls line up
Nov 19, 2021
2197004
Remove unused goal_num_ites
Nov 19, 2021
6b43d88
Unify is_point_affine and is_in_g1_impl calls
Nov 19, 2021
52ccdb3
Don't unfold uncompress_E1_imp in postcond proof
Nov 19, 2021
65eadde
Simplify mult by 1
Nov 19, 2021
bad752a
n=1 case goes through!
Nov 20, 2021
5a839ac
Remove bad_* thms
Nov 20, 2021
b07d9d0
Remove aggreate_n variable
Dec 1, 2021
1a1e5f0
N=3 proof
Dec 1, 2021
e849a4f
Restore unfold_aggregate_loop_1_thm
Dec 3, 2021
113cab2
N=4 preconditions
Dec 3, 2021
806e344
N=4 proof
Dec 3, 2021
a15035c
Prove aggregate_loop unfolders
Dec 3, 2021
68f80a1
Remove some outdated TODOs
Dec 3, 2021
039685b
Prove finalverify_core_verify_thm
Dec 3, 2021
f82ace9
Add normalization to affinify_abs_z_1_thm and prove
Dec 3, 2021
440397c
!is_point_O check for is_point_projective_E_affine_thm and prove
Dec 4, 2021
10f559d
finalverify B proof
Dec 8, 2021
3fbbeb8
blst_pairing_aggregate_pk_in_g1_null_sig_0_ov proof
Dec 9, 2021
a757a7c
blst_pairing_aggregate_pk_in_g1_null_sig_1_first_commit_ov
Dec 9, 2021
48c7089
blst_pairing_aggregate_pk_in_g1_null_sig_1_nth_commit_ov proof
Dec 9, 2021
01ef97f
Prove blst_pairing_aggregate_pk_in_g1_sig_ov
Dec 9, 2021
69f2dbe
AggregateVerify B spec
Dec 10, 2021
b3d855b
Precondition proof for N=1
Dec 11, 2021
76be245
Port over n9 thms
Dec 13, 2021
fe85b36
N=1 B proof
Dec 14, 2021
3014d5e
B N=3 preconditions all go through
Dec 15, 2021
6844378
B N=3 proofs go through
Dec 15, 2021
c566ad2
B N=4 proof
Dec 15, 2021
e5f5e6d
Prove finalverify_B_core_verify_thm
Dec 15, 2021
cf22f92
Prove some intermediate theorems
Dec 15, 2021
b8b8f98
Prove normalize_uncompress_E2_OK_{0,1}_thm
Dec 16, 2021
d1003c5
C changes
Dec 17, 2021
0d53ebe
Move aggregate patch to the right place
Dec 17, 2021
9005a23
Use hash_to_curve_opt everywhere
Dec 17, 2021
e471a2d
Cleanup sk_to_pk A proof
Dec 18, 2021
a42b2be
Move KeyValidate_A proof
Dec 20, 2021
76c290c
Move BasicSignA proof
Dec 20, 2021
8855f81
Move BasicVerify_A Proof
Dec 20, 2021
0c74794
Clean up SkToPk_B proof
Dec 20, 2021
56d5972
Clean up KeyValidate_B proof
Dec 20, 2021
d0aeff8
Clean up BasicSign_B proof
Dec 20, 2021
0ced490
Clean up BasicVerify_B proof
Dec 20, 2021
42bf47c
Some aggregate verify A cleanup
Dec 21, 2021
63c2ab8
Consolidate aggregate verify ovs
Dec 21, 2021
b8ba4eb
Consolidate aggregate_verify proofs
Dec 21, 2021
7b7ff40
Initial cleanup of aggregate verify B proof + prove null aug core verify
Dec 21, 2021
e09b63d
Unify blst_pairing_aggregate_pk_in_g1_null_sig proofs
Dec 21, 2021
6976ee7
Unify aggregate verify B proofs
Dec 21, 2021
24e95fe
Fix broken use of verify_blst_core_verify_pk_in_g1_null_aug
Dec 21, 2021
994dd20
Cleanup
Dec 22, 2021
5ce1306
Final cleanup
Dec 22, 2021
977c8a3
Fix aggregate verify memory safety proofs to work with N_MAX=2 patch
Dec 22, 2021
d76918d
Address missed documentation TODO
Dec 22, 2021
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
13 changes: 13 additions & 0 deletions patches/blst/aggregate.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/src/aggregate.c b/src/aggregate.c
index 50f6557..b8b7bd4 100644
--- a/src/aggregate.c
+++ b/src/aggregate.c
@@ -37,7 +37,7 @@
*/

#ifndef N_MAX
-# define N_MAX 8
+# define N_MAX 2
#endif

typedef union { POINTonE1 e1; POINTonE2 e2; } AggregatedSignature;
50 changes: 48 additions & 2 deletions patches/blst/blst_header.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/bindings/blst.h b/bindings/blst.h
index 3a333b1..cbd3642 100644
index 3a333b1..72b6c1c 100644
--- a/bindings/blst.h
+++ b/bindings/blst.h
@@ -168,10 +168,10 @@ bool blst_p1_is_equal(const blst_p1 *a, const blst_p1 *b);
Expand Down Expand Up @@ -30,7 +30,53 @@ index 3a333b1..cbd3642 100644
const blst_p2_affine *blst_p2_affine_generator();

/*
@@ -351,7 +351,7 @@ BLST_ERROR blst_core_verify_pk_in_g1(const blst_p1_affine *pk,
@@ -279,11 +279,25 @@ void blst_miller_loop_lines(blst_fp12 *ret, const blst_fp6 Qlines[68],
#ifdef __BLST_CGO__
typedef limb_t blst_pairing;
#else
-typedef struct {} blst_pairing;
+#ifndef N_MAX
+# define N_MAX 2
+#endif
+
+typedef union { blst_p1 e1; blst_p2 e2; } AggregatedSignature;
+typedef struct blst_pairing_st {
+ unsigned int ctrl;
+ unsigned int nelems;
+ const void *DST;
+ size_t DST_len;
+ blst_fp12 GT;
+ AggregatedSignature AggrSign;
+ blst_p2_affine Q[N_MAX];
+ blst_p1_affine P[N_MAX];
+} blst_pairing;
#endif

size_t blst_pairing_sizeof();
-void blst_pairing_init(blst_pairing *new_ctx, bool hash_or_encode,
+void blst_pairing_init(blst_pairing *new_ctx, int hash_or_encode,
const byte *DST DEFNULL, size_t DST_len DEFNULL);
const byte *blst_pairing_get_dst(const blst_pairing *ctx);
void blst_pairing_commit(blst_pairing *ctx);
@@ -318,7 +332,7 @@ BLST_ERROR blst_pairing_mul_n_aggregate_pk_in_g1(blst_pairing *ctx,
const byte *aug DEFNULL,
size_t aug_len DEFNULL);
BLST_ERROR blst_pairing_merge(blst_pairing *ctx, const blst_pairing *ctx1);
-bool blst_pairing_finalverify(const blst_pairing *ctx,
+limb_t blst_pairing_finalverify(const blst_pairing *ctx,
const blst_fp12 *gtsig DEFNULL);


@@ -343,7 +357,7 @@ void blst_aggregated_in_g2(blst_fp12 *out, const blst_p2_affine *signature);
*/
BLST_ERROR blst_core_verify_pk_in_g1(const blst_p1_affine *pk,
const blst_p2_affine *signature,
- bool hash_or_encode,
+ int hash_or_encode,
const byte *msg, size_t msg_len,
const byte *DST DEFNULL,
size_t DST_len DEFNULL,
@@ -351,7 +365,7 @@ BLST_ERROR blst_core_verify_pk_in_g1(const blst_p1_affine *pk,
size_t aug_len DEFNULL);
BLST_ERROR blst_core_verify_pk_in_g2(const blst_p2_affine *pk,
const blst_p1_affine *signature,
Expand Down
4 changes: 2 additions & 2 deletions proof/aggregate.saw
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let AGGR_GT_SET = {{ 32:[32] }};
let AGGR_HASH_OR_ENCODE = {{ 64:[32] }};
let MIN_SIG_OR_PK = {{ AGGR_MIN_SIG || AGGR_MIN_PK }};

let N_MAX = 8; // NOTE: must match N_MAX defined in C code
let N_MAX = 2; // NOTE: must match N_MAX defined in C code

let {{ is_in_G1 (p : ([6][64], [6][64])) = (undefined:[64]) }}; // NOTE: the goal is to leave it uninterpreted
let POINTonE1_in_G1_spec = do {
Expand Down Expand Up @@ -296,7 +296,7 @@ let overrides = foldr concat [hash_to_field_ovs, ec_ops_overrides, assembly_over

pairing_init_ov <- verify "blst_pairing_init" [] (blst_pairing_init_spec 8);

let aggregate_ns = [0,1,7]; // aggregate_... calls miller_loop_n for nelems+1
let aggregate_ns = [0,1]; // aggregate_... calls miller_loop_n for nelems+1

let make_aggregate_pk_in_g1_ov null_sig nelems = verify_unint "blst_pairing_aggregate_pk_in_g1" overrides ["is_in_G2"] (blst_pairing_aggregate_pk_in_spec DST_len msg_len aug_len nelems null_sig false); // null_sig should be 0 or 1
aggregate_pk_in_g1_null_sig_ovs <- for aggregate_ns (make_aggregate_pk_in_g1_ov 1);
Expand Down
4 changes: 2 additions & 2 deletions proof/aggregate_in_g1.saw
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ let overrides = foldr concat [vec_overrides,curve_operations_e1_ovs] [POINTonE1_
uncompress_not_point_O <- admit_cryptol {{ \x -> (is_point_O E (uncompress_E1_OK x)) == if uncompress_E1_x_fp x != Fp.field_zero then False else apply is_point_O E (uncompress_E1_OK x) }};

// decompression yields a point on the curve
uncompress_on_curve <- admit_cryptol {{ \x -> (is_point_affine E (uncompress_E1_OK x)) == True }};
uncompress_E1_on_curve <- admit_cryptol {{ \x -> (is_point_affine E (uncompress_E1_OK x)) == True }};

// Proofs

let simpset = addsimps (concat_all [e1_curve_op_thms, POINTonE1_thms, [normalize_uncompress_OK_thm, uncompress_not_point_O, uncompress_on_curve]]) fp_simpset; // uncompress_not_point_O and uncompress_on_curve are there to satisfy the preconditions of the subgroup check
let simpset = addsimps (concat_all [e1_curve_op_thms, POINTonE1_thms, [normalize_uncompress_OK_thm, uncompress_not_point_O, uncompress_E1_on_curve]]) fp_simpset; // uncompress_not_point_O and uncompress_E1_on_curve are there to satisfy the preconditions of the subgroup check

let fp_unit_rep = run ( eval_term {{ (fp_rep Fp.field_unit):[6][64] }} ); // NOTE: this results in type `([6][64])` (a one-tuple?) instead of `[6][64]`, but not in newer versions of SAW.

Expand Down
127 changes: 95 additions & 32 deletions proof/bls_operations.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#include "blst.h"
#include <stdio.h> // for NULL

// TODO: Move
#include <string.h> // for memcmp

// Two variants:
// _A: min signature size
// _B: min pk size

// Explicitly note that demo_DST_A is 43 bytes to avoid the null terminator
// (needed for SAW to treat the allocation as 32 bytes)
// demo_DST_A and demo_DST_B are 43 bytes to avoid the null terminator. This
// is needed for SAW to treat the allocations as 43 bytes.
byte demo_DST_A[43] = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_";
byte demo_DST_B[43] = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_";

Expand All @@ -33,12 +32,6 @@ limb_t demo_KeyValidate_A(const unsigned char in[96]) {
blst_p2_affine pk;
BLST_ERROR r;
r = blst_p2_uncompress(&pk, in);
/*
return r == BLST_SUCCESS &&
blst_p2_affine_on_curve(&pk) &&
!blst_p2_affine_is_inf(&pk) &&
blst_p2_affine_in_g2(&pk);
*/
if (r != BLST_SUCCESS) return 0;
if (! blst_p2_affine_on_curve(&pk)) return 0;
if (blst_p2_affine_is_inf(&pk)) return 0;
Expand All @@ -62,15 +55,8 @@ limb_t demo_KeyValidate_B(const unsigned char in[48]) {

void demo_BasicSign_A(byte out[48], const blst_scalar *SK,
const byte *message, size_t message_len) {
// TODO: Figure out how to use globals in SAW?
//const byte local_DST_A[] = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_";
blst_p1 Q1, Q2;
// TODO: Double check, but I think aug is supposed to be a public key? That
// will determine the size it should be.
// TODO: Is DST_len supposted to include the null terminator? It's 44 with
// the null terminator, and 43 without.
blst_hash_to_g1(&Q1, message, message_len, demo_DST_A, 43, NULL, 0); // no "aug" string
// blst_p1_mult(&Q, &Q, SK, 256); // or 255?
blst_sign_pk_in_g2(&Q2, &Q1, SK);
blst_p1_compress(out, &Q2);
};
Expand All @@ -97,21 +83,15 @@ limb_t demo_BasicVerify_A(const byte sig[48], const byte pk[96], const byte *mes

if (!demo_KeyValidate_A(pk)) return 0;

// TODO: Use KeyValidate below instead to better match the spec?
// uncompress and check the pub key
if (blst_p2_uncompress(&PK, pk) != BLST_SUCCESS) return 0;
/*
if (! blst_p2_affine_on_curve(&PK)) return 0;
if (blst_p2_affine_is_inf(&PK)) return 0;
if (! blst_p2_affine_in_g2(&PK)) return 0;
*/

if (blst_core_verify_pk_in_g2(&PK, &R, 1, message, message_len, demo_DST_A, 43, NULL, 0) != BLST_SUCCESS)
return 0;
return 1;
};

bool demo_BasicVerify_B(const byte sig[96], const byte pk[48], const byte *message, size_t message_len) {
limb_t demo_BasicVerify_B(const byte sig[96], const byte pk[48], const byte *message, size_t message_len) {
blst_p2_affine R;
blst_p2 Q;
blst_p1_affine PK;
Expand All @@ -121,18 +101,101 @@ bool demo_BasicVerify_B(const byte sig[96], const byte pk[48], const byte *messa
if (blst_p2_affine_is_inf(&R)) return 0;
if (! blst_p2_affine_in_g2(&R)) return 0;

// TODO: Maybe remove the above checks if the override handles error cases.
// Can't remove pubkey checks? (Same goes for A variant)
if (!demo_KeyValidate_B(pk)) return 0;

// uncompress and check the pub key
if (blst_p1_uncompress(&PK, pk) != BLST_SUCCESS) return 0;
if (! blst_p1_affine_on_curve(&PK)) return 0;
if (blst_p1_affine_is_inf(&PK)) return 0;
if (! blst_p1_affine_in_g1(&PK)) return 0;


// TODO: fix DST string
if (blst_core_verify_pk_in_g1(&PK, &R, 1, message, message_len, demo_DST_A, 43, NULL, 0) != BLST_SUCCESS)
if (blst_core_verify_pk_in_g1(&PK, &R, 1, message, message_len, demo_DST_B, 43, NULL, 0) != BLST_SUCCESS)
return 0;
return 1;
};

// Assert no two messages are equal
limb_t all_distinct(size_t n, size_t message_len, const byte messages[n][message_len]) {
for (size_t i; i < n; ++i) {
for (size_t j = i+1; j < n; ++j) {
if (memcmp(messages[i], messages[j], message_len)) return 0;
}
}
return 1;
}

limb_t demo_BasicAggregateVerify_A(size_t n,
size_t message_len,
const byte pks[n][96],
const byte messages[n][message_len],
const byte sig[48]) {
if (!all_distinct(n, message_len, messages)) return 0;

// uncompress and check the sig
blst_p1_affine R;
if (blst_p1_uncompress(&R, sig) != BLST_SUCCESS) return 0;
if (! blst_p1_affine_on_curve(&R)) return 0;
if (blst_p1_affine_is_inf(&R)) return 0;
if (! blst_p1_affine_in_g1(&R)) return 0;

// Create aggregate verify context
blst_pairing ctx;
blst_pairing_init(&ctx, 1, demo_DST_A, 43);

for (size_t i = 0; i < n; ++i) {
const byte* pk = pks[i];
// Check and Uncompress PK
if (!demo_KeyValidate_A(pk)) return 0;

blst_p2_affine PK;
if (blst_p2_uncompress(&PK, pk) != BLST_SUCCESS) return 0;

// Aggregate
if (blst_pairing_aggregate_pk_in_g2(&ctx,
&PK,
i ? NULL : &R,
messages[i],
message_len,
NULL,
0) != BLST_SUCCESS) return 0;
}
blst_pairing_commit(&ctx);
if (!blst_pairing_finalverify(&ctx, NULL)) return 0;
return 1;
}

limb_t demo_BasicAggregateVerify_B(size_t n,
size_t message_len,
const byte pks[n][48],
const byte messages[n][message_len],
const byte sig[96]) {
if (!all_distinct(n, message_len, messages)) return 0;

// uncompress and check the sig
blst_p2_affine R;
if (blst_p2_uncompress(&R, sig) != BLST_SUCCESS) return 0;
if (! blst_p2_affine_on_curve(&R)) return 0;
if (blst_p2_affine_is_inf(&R)) return 0;
if (! blst_p2_affine_in_g2(&R)) return 0;

// Create aggregate verify context
blst_pairing ctx;
blst_pairing_init(&ctx, 1, demo_DST_B, 43);

for (size_t i = 0; i < n; ++i) {
const byte* pk = pks[i];
// Check and Uncompress PK
if (!demo_KeyValidate_B(pk)) return 0;
blst_p1_affine PK;
if (blst_p1_uncompress(&PK, pk) != BLST_SUCCESS) return 0;

// Aggregate
if (blst_pairing_aggregate_pk_in_g1(&ctx,
&PK,
i ? NULL : &R,
messages[i],
message_len,
NULL,
0) != BLST_SUCCESS) return 0;
}
blst_pairing_commit(&ctx);
if (!blst_pairing_finalverify(&ctx, NULL)) return 0;
return 1;
}
Loading