-
Notifications
You must be signed in to change notification settings - Fork 8
/
bigint.cairo
70 lines (64 loc) · 2.25 KB
/
bigint.cairo
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
// The base of the representation.
const BASE = 2 ** 86;
// Represents an integer defined by
// d0 + BASE * d1 + BASE**2 * d2.
// Note that the limbs (d_i) are NOT restricted to the range [0, BASE) and in particular they
// can be negative.
// In most cases this is used to represent a secp256k1 field element.
struct UnreducedBigInt3 {
d0: felt,
d1: felt,
d2: felt,
}
// Same as UnreducedBigInt3, except that d0, d1 and d2 must be in the range [0, 3 * BASE).
// In most cases this is used to represent a secp256k1 field element.
struct BigInt3 {
d0: felt,
d1: felt,
d2: felt,
}
// Represents a big integer: sum_i(BASE**i * d_i).
// Note that the limbs (d_i) are NOT restricted to the range [0, BASE) and in particular they
// can be negative.
struct UnreducedBigInt5 {
d0: felt,
d1: felt,
d2: felt,
d3: felt,
d4: felt,
}
func bigint_mul(x: BigInt3, y: BigInt3) -> (res: UnreducedBigInt5) {
return (
UnreducedBigInt5(
d0=x.d0 * y.d0,
d1=x.d0 * y.d1 + x.d1 * y.d0,
d2=x.d0 * y.d2 + x.d1 * y.d1 + x.d2 * y.d0,
d3=x.d1 * y.d2 + x.d2 * y.d1,
d4=x.d2 * y.d2),
);
}
// Returns a BigInt3 instance whose value is controlled by a prover hint.
//
// Soundness guarantee: each limb is in the range [0, 3 * BASE).
// Completeness guarantee (honest prover): the value is in reduced form and in particular,
// each limb is in the range [0, BASE).
//
// Hint arguments: value.
func nondet_bigint3{range_check_ptr}() -> (res: BigInt3) {
// The result should be at the end of the stack after the function returns.
let res: BigInt3 = [cast(ap + 5, BigInt3*)];
%{
from starkware.cairo.common.cairo_secp.secp_utils import split
segments.write_arg(ids.res.address_, split(value))
%}
// The maximal possible sum of the limbs, assuming each of them is in the range [0, BASE).
const MAX_SUM = 3 * (BASE - 1);
assert [range_check_ptr] = MAX_SUM - (res.d0 + res.d1 + res.d2);
// Prepare the result at the end of the stack.
tempvar range_check_ptr = range_check_ptr + 4;
[range_check_ptr - 3] = res.d0, ap++;
[range_check_ptr - 2] = res.d1, ap++;
[range_check_ptr - 1] = res.d2, ap++;
static_assert &res + BigInt3.SIZE == ap;
return (res=res);
}