-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathPrimeFieldElement0.sol
100 lines (87 loc) · 3.24 KB
/
PrimeFieldElement0.sol
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
/*
Copyright 2019-2022 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;
contract PrimeFieldElement0 {
uint256 internal constant K_MODULUS =
0x800000000000011000000000000000000000000000000000000000000000001;
uint256 internal constant K_MONTGOMERY_R =
0x7fffffffffffdf0ffffffffffffffffffffffffffffffffffffffffffffffe1;
uint256 internal constant K_MONTGOMERY_R_INV =
0x40000000000001100000000000012100000000000000000000000000000000;
uint256 internal constant GENERATOR_VAL = 3;
uint256 internal constant ONE_VAL = 1;
function fromMontgomery(uint256 val) internal pure returns (uint256 res) {
// uint256 res = fmul(val, kMontgomeryRInv);
assembly {
res := mulmod(val, K_MONTGOMERY_R_INV, K_MODULUS)
}
return res;
}
function fromMontgomeryBytes(bytes32 bs) internal pure returns (uint256) {
// Assuming bs is a 256bit bytes object, in Montgomery form, it is read into a field
// element.
uint256 res = uint256(bs);
return fromMontgomery(res);
}
function toMontgomeryInt(uint256 val) internal pure returns (uint256 res) {
//uint256 res = fmul(val, kMontgomeryR);
assembly {
res := mulmod(val, K_MONTGOMERY_R, K_MODULUS)
}
return res;
}
function fmul(uint256 a, uint256 b) internal pure returns (uint256 res) {
//uint256 res = mulmod(a, b, kModulus);
assembly {
res := mulmod(a, b, K_MODULUS)
}
return res;
}
function fadd(uint256 a, uint256 b) internal pure returns (uint256 res) {
// uint256 res = addmod(a, b, kModulus);
assembly {
res := addmod(a, b, K_MODULUS)
}
return res;
}
function fsub(uint256 a, uint256 b) internal pure returns (uint256 res) {
// uint256 res = addmod(a, kModulus - b, kModulus);
assembly {
res := addmod(a, sub(K_MODULUS, b), K_MODULUS)
}
return res;
}
function fpow(uint256 val, uint256 exp) internal view returns (uint256) {
return expmod(val, exp, K_MODULUS);
}
function expmod(
uint256 base,
uint256 exponent,
uint256 modulus
) private view returns (uint256 res) {
assembly {
res := 1
for { } gt(exponent, 0) { } {
if mod(exponent, 2) {
res := mulmod(res, base, modulus)
}
base := mulmod(base, base, modulus)
exponent := shr(1, exponent)
}
}
}
function inverse(uint256 val) internal view returns (uint256) {
return expmod(val, K_MODULUS - 2, K_MODULUS);
}
}