Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

arkworks integration #13031

Merged
merged 432 commits into from Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
432 commits
Select commit Hold shift + click to select a range
5a8e08a
fix
Feb 8, 2023
975e8e7
fix
Feb 8, 2023
8330c7a
fix
Feb 8, 2023
c1d4487
fix
Feb 8, 2023
8eb12b5
fix
Feb 8, 2023
5b4ed3f
fix
Feb 8, 2023
f1db0e5
fix
Feb 8, 2023
ef71a21
fix
Feb 8, 2023
345b565
fix
Feb 8, 2023
1c82d5c
fix
Feb 8, 2023
e1776eb
fix
Feb 8, 2023
a15345b
fix
Feb 8, 2023
37ede02
fix
Feb 8, 2023
a3371a1
fix
Feb 9, 2023
8240460
fix compression
Feb 9, 2023
82acb85
fix compression
Feb 9, 2023
731b042
fix compression
Feb 9, 2023
4e93862
Merge branch 'master' into no-compression
Feb 9, 2023
81f0881
fix compression
Feb 10, 2023
f0a95d3
fix compression
Feb 10, 2023
10b050f
fix std leak
Feb 10, 2023
80c606f
Merge branch 'master' into no-compression
Feb 11, 2023
ada044c
fix std leak
Feb 11, 2023
3c8d315
fix std leak
Feb 11, 2023
0f581bf
merge master
Feb 11, 2023
24d18f8
merge master
Feb 11, 2023
7301014
Merge branch 'master' into achimcc/arkworks-integration
Feb 11, 2023
7f1a96b
Merge branch 'no-compression' into achimcc/arkworks-integration
Feb 12, 2023
55f245a
Merge branch 'master' into achimcc/arkworks-integration
Feb 12, 2023
21e609e
Merge branch 'master' into achimcc/arkworks-integration
Feb 15, 2023
2564fed
cargo update
Feb 15, 2023
914c5d4
Merge branch 'master' into achimcc/arkworks-integration
Feb 17, 2023
5f2a075
cargo update
Feb 17, 2023
50b0341
Merge branch 'master' into achimcc/arkworks-integration
Feb 18, 2023
684ae64
cargo update
Feb 18, 2023
800b28e
Merge branch 'master' into achimcc/arkworks-integration
Feb 21, 2023
8dc3ee3
cargo update
Feb 21, 2023
df89262
Merge branch 'master' into achimcc/arkworks-integration
Mar 1, 2023
2ddc471
cargo update
Mar 1, 2023
43aba0d
Merge branch 'master' into achimcc/arkworks-integration
Mar 3, 2023
16840ab
use serialize_result
Mar 5, 2023
1c808d7
Merge branch 'master' into achimcc/arkworks-integration
Mar 5, 2023
4efe3af
Merge branch 'master' into achimcc/arkworks-integration
Mar 6, 2023
7dda160
cargo update
Mar 6, 2023
2e436d8
Merge branch 'master' into achimcc/arkworks-integration
Mar 6, 2023
acff5f8
cargo update
Mar 8, 2023
3deecae
Merge branch 'master' into achimcc/arkworks-integration
Mar 8, 2023
3f95117
cargo update
Mar 8, 2023
417dfa4
Merge branch 'master' into achimcc/arkworks-integration
Mar 10, 2023
e895c73
cargo update
Mar 10, 2023
d1d5d74
reduce boilerplate code
Mar 10, 2023
6ed1383
Merge branch 'master' into achimcc/arkworks-integration
Mar 10, 2023
6de9638
remove host function muls
Mar 10, 2023
f4dfa2a
reduce boilerplate code
Mar 10, 2023
d830e86
remove patches
Mar 11, 2023
698dcb9
uuse correct ark-substrate branch
Mar 11, 2023
abbfb1c
reduce boilerplate code
Mar 12, 2023
ddf5181
Merge branch 'master' into achimcc/arkworks-integration
Mar 12, 2023
39c7f4a
cleanup
Mar 12, 2023
4bb0653
cleanup
Mar 12, 2023
235022a
proper error handling
Mar 15, 2023
80635ee
derive serialize for error
Mar 15, 2023
03dc219
proper error handling
Mar 15, 2023
c4b2f04
proper error handling
Mar 15, 2023
2160e93
proper error handling
Mar 15, 2023
7c183e9
derive Debug for PairingError
Mar 16, 2023
86dd3fd
sp-arkworks path
Mar 16, 2023
3dabce2
Merge branch 'master' into achimcc/arkworks-integration
Mar 17, 2023
4807505
cargo update
Mar 17, 2023
1e6c178
adopt tests to error handling
Mar 17, 2023
b69de4d
fix tests
Mar 17, 2023
4e49a4f
cargo update
Mar 17, 2023
6bd1338
remove results
Mar 17, 2023
08c9521
deserialize as G2Affine
Mar 17, 2023
6e49a08
cargo update
Mar 17, 2023
ab35a7a
add codex index to PairingError
Mar 18, 2023
4389714
replace Vec<Vec<u8>>
Mar 18, 2023
4d3b13c
replace Vec<Vec<u8>>
Mar 18, 2023
1ddd6b8
use into_iter for chunks
Mar 18, 2023
67987ae
use chunks for scalars
Mar 18, 2023
c6a7609
fix ersialized_size
Mar 18, 2023
344cfff
use into
Mar 18, 2023
9167d59
collect as vec
Mar 18, 2023
dd3f809
collect as vec
Mar 18, 2023
db18dca
no collect Vec
Mar 18, 2023
2e31d91
use into_iter
Mar 18, 2023
5a103ac
import AffineRepr
Mar 18, 2023
c89e963
fix typo
Mar 18, 2023
15898da
cargo update
Mar 18, 2023
e56a088
new serialization
Mar 19, 2023
c12045d
fix typo
Mar 19, 2023
de3cfbd
unwrap results
Mar 19, 2023
b0df1e1
unwrap results
Mar 19, 2023
9eacba9
use correct deserialization
Mar 19, 2023
eef4c77
fix bugs, cleanup
Mar 19, 2023
b85de86
correct len
Mar 19, 2023
2b1cd00
vec without capacity
Mar 19, 2023
fce6686
Revert "vec without capacity"
Mar 19, 2023
ab4d2b8
Revert "correct len"
Mar 19, 2023
435dab5
Revert "fix bugs, cleanup"
Mar 19, 2023
59f25fb
Revert "use correct deserialization"
Mar 19, 2023
b011681
Revert "unwrap results"
Mar 19, 2023
6a571d0
Revert "unwrap results"
Mar 19, 2023
f1eecf9
Revert "fix typo"
Mar 19, 2023
5999e11
Revert "new serialization"
Mar 19, 2023
531eacb
Revert "cargo update"
Mar 19, 2023
bac66ab
Revert "fix typo"
Mar 19, 2023
4ad8e32
Revert "import AffineRepr"
Mar 19, 2023
03e95bb
Revert "use into_iter"
Mar 19, 2023
8649035
Revert "no collect Vec"
Mar 19, 2023
af14139
Revert "collect as vec"
Mar 19, 2023
e299101
Revert "collect as vec"
Mar 19, 2023
eec08b5
Revert "use into"
Mar 19, 2023
43a689d
Revert "fix ersialized_size"
Mar 19, 2023
757868e
Revert "use chunks for scalars"
Mar 19, 2023
24a11d7
Revert "use into_iter for chunks"
Mar 19, 2023
b516562
Revert "replace Vec<Vec<u8>>"
Mar 19, 2023
573cd48
cargo update
Mar 19, 2023
9551b75
cargo update
Mar 19, 2023
f417849
Revert "replace Vec<Vec<u8>>"
Mar 19, 2023
9138da1
cargo update
Mar 19, 2023
db922ca
add error
Mar 20, 2023
b35fb25
add error
Mar 20, 2023
868d4ac
add error
Mar 20, 2023
9fe204e
fix typo
Mar 20, 2023
0aa20df
fix imports
Mar 20, 2023
3f8dd79
import coded
Mar 20, 2023
72c52ff
import codec
Mar 20, 2023
c282f62
import PairingError
Mar 20, 2023
d4eb534
fix patches
Mar 20, 2023
bb8b3d0
sp-arkworks
Mar 20, 2023
031485b
sp-arkworks
Mar 20, 2023
3ebd14d
Merge branch 'master' into arkworks-host-function-mul
Mar 20, 2023
2a5a45d
use random values for multiplications
Mar 21, 2023
4231dee
Merge branch 'arkworks-host-function-mul' into achimcc/arkworks-integ…
Mar 21, 2023
30b3900
Merge branch 'master' into achimcc/arkworks-integration
Mar 21, 2023
7a0e6a1
cargo update
Mar 21, 2023
5077864
fix imports
Mar 21, 2023
1544a0a
fix imports
Mar 21, 2023
1670d62
add host functions
Mar 21, 2023
7b92f2f
re-add mul impls
Mar 21, 2023
525b1e0
cargo update
Mar 21, 2023
9c044bb
cargo update
Mar 21, 2023
b70cb73
Merge branch 'master' into achimcc/arkworks-integration
Mar 21, 2023
f1a6f60
cargo update
Mar 21, 2023
dc3bb4f
cargo update
Mar 23, 2023
00ae8b9
cargo update
Mar 23, 2023
e3acad2
cargo update
Mar 23, 2023
1e09985
cargo update
Mar 23, 2023
54c6965
PairingError -> ()
Mar 24, 2023
cdc6869
remove PairingError
Mar 24, 2023
5a7843b
Merge branch 'master' into achimcc/arkworks-integration
Mar 24, 2023
b08e465
cargo update
Mar 24, 2023
cb95d98
Merge branch 'master' into achimcc/arkworks-integration
Mar 25, 2023
9da264a
cargo update
Mar 25, 2023
3806b04
Merge branch 'master' into achimcc/arkworks-integration
Mar 28, 2023
db96f33
cargo update
Mar 28, 2023
e81c093
reduce boilerplate code
Apr 5, 2023
834a314
Merge branch 'master' into achimcc/arkworks-integration
Apr 5, 2023
7ef2caa
cargo update
Apr 5, 2023
1501c51
update comments
Apr 5, 2023
8f0fcb6
Merge branch 'master' into achimcc/arkworks-integration
Apr 8, 2023
9b3c36d
cargo update
Apr 8, 2023
ca487ec
optimize code quality
Apr 13, 2023
a2b185f
Merge branch 'master' into achimcc/arkworks-integration
Apr 13, 2023
70bcea0
use ark_scale (#13954)
achimcc Apr 20, 2023
2f8579e
hazmat
Apr 21, 2023
8aada1d
ed curves, use ArkScaleProjective
Apr 21, 2023
5e86d97
Achimcc/arkworks integration remove affine hostcalls (#13971)
achimcc Apr 21, 2023
828245b
Merge branch 'master' into achimcc/arkworks-integration
Apr 21, 2023
ee0f2be
ark-substrate: use main branch
Apr 21, 2023
89b4e59
cargo update
Apr 21, 2023
9d3e6fc
Achimcc/arkworks integration bandersnatch (#13977)
achimcc Apr 22, 2023
b78109c
cargo update
Apr 22, 2023
f27bcf9
Merge branch 'master' into achimcc/arkworks-integration
Apr 22, 2023
5023e15
cargo update
Apr 22, 2023
fad84e0
fix tests
Apr 22, 2023
e0e3a5a
cleanup
Apr 22, 2023
1c9e8b1
cleanup
Apr 22, 2023
1f5ded9
fix tests
Apr 22, 2023
fbca295
refactor tests
Apr 24, 2023
b23d63f
cargo update
Apr 24, 2023
61fc500
Merge branch 'master' into achimcc/arkworks-integration
Apr 26, 2023
a7f7bde
cargo update
Apr 26, 2023
763c617
Merge branch 'master' into achimcc/arkworks-integration
Apr 27, 2023
ab3a111
cargo update
Apr 27, 2023
909df35
refactor tests
Apr 27, 2023
9fdee99
Merge branch 'master' into achimcc/arkworks-integration
Apr 28, 2023
e4c507d
cleanup & update tests
Apr 28, 2023
bc27817
Merge branch 'master' into achimcc/arkworks-integration
May 1, 2023
c00b5ce
upgrade arkworks/algebra
May 1, 2023
b529096
Merge branch 'master' into achimcc/arkworks-integration
May 3, 2023
73e4f64
cargo update
May 3, 2023
706361a
Merge branch 'master' into achimcc/arkworks-integration
May 8, 2023
e974cc8
adopt tests
May 8, 2023
d0802ce
versioning ark-substrate
May 9, 2023
731a254
Merge branch 'master' into achimcc/arkworks-integration
May 9, 2023
454ef84
Merge branch 'master' into achimcc/arkworks-integration
May 9, 2023
5fb318d
cargo update
May 9, 2023
a9d85bf
Merge branch 'master' into achimcc/arkworks-integration
May 15, 2023
945ba00
remove patched deps
May 15, 2023
ba068d3
bump ark-scale
May 16, 2023
4ea6621
Merge branch 'master' into achimcc/arkworks-integration
May 16, 2023
57e4def
use crates-io deps
May 16, 2023
eb65ffc
Merge branch 'master' into achimcc/arkworks-integration
May 22, 2023
047b297
fix doc comments
May 22, 2023
03f5d13
Cargo.toml, linebreaks at end
May 22, 2023
69e1d94
reorgainze tests
May 22, 2023
fdd5cde
sp-arkworks -> sp-crypto-ec-utils
May 22, 2023
39dc3ba
move host functions to crypto-ec-utils
May 22, 2023
ce271ba
fmt
May 22, 2023
01ae9d5
Merge branch 'master' into achimcc/arkworks-integration
May 22, 2023
cacc216
remove sp-ec-crypto-utils from io
May 22, 2023
7199d1f
remove unwrap from te msm
May 22, 2023
058614d
remove elliptic_curves references in test
May 22, 2023
f07d8d4
elliptic_curves references in test
May 22, 2023
162b190
update doc comments
May 23, 2023
965e520
remove warn missing docs
May 23, 2023
88dd4a3
fmt
May 23, 2023
8f00f2f
Merge branch 'master' into achimcc/arkworks-integration
May 23, 2023
3dcacc9
cargo update
May 23, 2023
25f863f
update doc comments
May 23, 2023
fa408ad
Merge branch 'master' into achimcc/arkworks-integration
May 24, 2023
6f23cae
cargo update
May 24, 2023
e0d4fba
Merge branch 'master' into achimcc/arkworks-integration
May 30, 2023
eba8b32
cargo update, bump arkworks, codec versions
May 30, 2023
19e67f9
Merge branch 'master' into achimcc/arkworks-integration
Jun 1, 2023
9988dcc
bump runtime version in sp-crypto-ec-utils
Jun 1, 2023
f906c5e
remove feature flag ec-utils-experimental
Jun 1, 2023
b7caa18
crypto-ec-utils -> crypto/ec-utils
Jun 1, 2023
99dd1d2
tests/ -> test-data/
Jun 1, 2023
3521242
update doc comments for signatures
Jun 2, 2023
e8c3056
Merge branch 'master' into achimcc/arkworks-integration
Jun 2, 2023
2d8334f
update comments
Jun 2, 2023
a0b375c
update doc comments for signatures
Jun 2, 2023
3e99300
fix doc comments
Jun 2, 2023
4d37a43
fix doc comments
Jun 2, 2023
ae6ce88
fix doc comments
Jun 2, 2023
d648ecf
fix doc comments
Jun 2, 2023
b189c00
fix doc comments
Jun 2, 2023
36cde85
Merge branch 'master' into achimcc/arkworks-integration
Jun 2, 2023
6fc40b9
cleanup
Jun 2, 2023
6161e64
fix doc comments
Jun 2, 2023
34402a4
cargo update
Jun 2, 2023
8ff1712
Merge branch 'master' into achimcc/arkworks-integration
Jun 2, 2023
36e11b6
Merge branch 'master' into achimcc/arkworks-integration
Jun 2, 2023
200df29
fix doc comments
Jun 5, 2023
fc68b51
Merge branch 'master' into achimcc/arkworks-integration
Jun 5, 2023
665dce2
Merge branch 'master' into achimcc/arkworks-integration
Jun 6, 2023
ba03141
cargo update
Jun 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
784 changes: 499 additions & 285 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -199,6 +199,7 @@ members = [
"primitives/core",
"primitives/core/hashing",
"primitives/core/hashing/proc-macro",
"primitives/crypto/ec-utils",
"primitives/database",
"primitives/debug-derive",
"primitives/externalities",
Expand Down
61 changes: 61 additions & 0 deletions primitives/crypto/ec-utils/Cargo.toml
@@ -0,0 +1,61 @@
[package]
name = "sp-crypto-ec-utils"
version = "0.4.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
license = "Apache-2.0"
homepage = "https://substrate.io"
repository = "https://github.com/paritytech/substrate/"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
ark-serialize = { version = "0.4.2", default-features = false }
ark-ff = { version = "0.4.2", default-features = false }
ark-ec = { version = "0.4.2", default-features = false }
ark-std = { version = "0.4.0", default-features = false }
ark-bls12-377 = { version = "0.4.0", features = ["curve"], default-features = false }
ark-bls12-381 = { version = "0.4.0", features = ["curve"], default-features = false }
ark-bw6-761 = { version = "0.4.0", default-features = false }
ark-ed-on-bls12-381-bandersnatch = { version = "0.4.0", default-features = false }
ark-ed-on-bls12-377 = { version = "0.4.0", default-features = false }
sp-std = { version = "8.0.0", path = "../../std", default-features = false }
codec = { package = "parity-scale-codec", version = "3.5.0", default-features = false }
ark-scale = { version = "0.0.3", features = ["hazmat"], default-features = false }
sp-runtime-interface = { version = "17.0.0", default-features = false, path = "../../runtime-interface" }

[dev-dependencies]
sp-io = { path = "../../io", default-features = false }
ark-algebra-test-templates = { version = "0.4.2", default-features = false }
sp-ark-models = { version = "0.4.0-beta", default-features = false }
sp-ark-bls12-377 = { version = "0.4.0-beta", default-features = false }
sp-ark-bls12-381 = { version = "0.4.0-beta", default-features = false }
sp-ark-bw6-761 = { version = "0.4.0-beta", default-features = false }
sp-ark-ed-on-bls12-377 = { version = "0.4.0-beta", default-features = false }
sp-ark-ed-on-bls12-381-bandersnatch = { version = "0.4.0-beta", default-features = false }

[features]
default = [ "std" ]
std = [
"ark-serialize/std",
"ark-ff/std",
"ark-ec/std",
"ark-std/std",
"ark-bls12-377/std",
"ark-bls12-381/std",
"ark-bw6-761/std",
"ark-ed-on-bls12-381-bandersnatch/std",
"ark-ed-on-bls12-377/std",
"sp-std/std",
"codec/std",
"ark-scale/std",
"sp-runtime-interface/std",
"sp-io/std",
"ark-algebra-test-templates/std",
"sp-ark-bls12-377/std",
"sp-ark-bls12-381/std",
"sp-ark-bw6-761/std",
"sp-ark-ed-on-bls12-377/std",
"sp-ark-ed-on-bls12-381-bandersnatch/std",
]
103 changes: 103 additions & 0 deletions primitives/crypto/ec-utils/src/bls12_377.rs
@@ -0,0 +1,103 @@
// This file is part of Substrate.

// Copyright (C) 2017-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

//! Support functions for bls12_377 to improve the performance of
//! multi_miller_loop, final_exponentiation, msm's and projective
//! multiplications by host function calls

use crate::utils::{
final_exponentiation_generic, msm_sw_generic, mul_projective_generic, multi_miller_loop_generic,
};
use ark_bls12_377::{g1, g2, Bls12_377};
use sp_std::vec::Vec;

/// Compute a multi miller loop through arkworks
pub fn multi_miller_loop(a: Vec<u8>, b: Vec<u8>) -> Result<Vec<u8>, ()> {
multi_miller_loop_generic::<Bls12_377>(a, b)
}

/// Compute a final exponentiation through arkworks
pub fn final_exponentiation(target: Vec<u8>) -> Result<Vec<u8>, ()> {
final_exponentiation_generic::<Bls12_377>(target)
}

/// Compute a multi scalar multiplication for short_weierstrass through
/// arkworks on G1.
pub fn msm_g1(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, ()> {
msm_sw_generic::<g1::Config>(bases, scalars)
}

/// Compute a multi scalar multiplication for short_weierstrass through
/// arkworks on G2.
pub fn msm_g2(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, ()> {
msm_sw_generic::<g2::Config>(bases, scalars)
}

/// Compute a projective scalar multiplication for short_weierstrass
/// through arkworks on G1.
pub fn mul_projective_g1(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
mul_projective_generic::<g1::Config>(base, scalar)
}

/// Compute a projective scalar multiplication for short_weierstrass
/// through arkworks on G2.
pub fn mul_projective_g2(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
mul_projective_generic::<g2::Config>(base, scalar)
}

#[cfg(test)]
mod tests {
use super::*;
use ark_algebra_test_templates::*;
use sp_ark_bls12_377::{
Bls12_377 as Bls12_377Host, G1Projective as G1ProjectiveHost,
G2Projective as G2ProjectiveHost, HostFunctions,
};

#[derive(PartialEq, Eq)]
struct Host;

impl HostFunctions for Host {
fn bls12_377_multi_miller_loop(a: Vec<u8>, b: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_377_multi_miller_loop(a, b)
}
fn bls12_377_final_exponentiation(f12: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_377_final_exponentiation(f12)
}
fn bls12_377_msm_g1(bases: Vec<u8>, bigints: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_377_msm_g1(bases, bigints)
}
fn bls12_377_msm_g2(bases: Vec<u8>, bigints: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_377_msm_g2(bases, bigints)
}
fn bls12_377_mul_projective_g1(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_377_mul_projective_g1(base, scalar)
}
fn bls12_377_mul_projective_g2(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_377_mul_projective_g2(base, scalar)
}
}

type Bls12_377 = Bls12_377Host<Host>;
type G1Projective = G1ProjectiveHost<Host>;
type G2Projective = G2ProjectiveHost<Host>;

test_group!(g1; G1Projective; sw);
test_group!(g2; G2Projective; sw);
test_group!(pairing_output; ark_ec::pairing::PairingOutput<Bls12_377>; msm);
test_pairing!(pairing; super::Bls12_377);
}
219 changes: 219 additions & 0 deletions primitives/crypto/ec-utils/src/bls12_381.rs
@@ -0,0 +1,219 @@
// This file is part of Substrate.

// Copyright (C) 2017-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

//! Support functions for bls12_381 to improve the performance of
//! multi_miller_loop, final_exponentiation, msm's and projective
//! multiplications by host function calls

use crate::utils::{
final_exponentiation_generic, msm_sw_generic, mul_projective_generic, multi_miller_loop_generic,
};
use ark_bls12_381::{g1, g2, Bls12_381};
use sp_std::vec::Vec;

/// Compute a multi miller loop through arkworks
pub fn multi_miller_loop(a: Vec<u8>, b: Vec<u8>) -> Result<Vec<u8>, ()> {
multi_miller_loop_generic::<Bls12_381>(a, b)
}

/// Compute a final exponentiation through arkworks
pub fn final_exponentiation(target: Vec<u8>) -> Result<Vec<u8>, ()> {
final_exponentiation_generic::<Bls12_381>(target)
}

/// Compute a multi scalar multiplication for short_weierstrass through
/// arkworks on G1.
pub fn msm_g1(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, ()> {
msm_sw_generic::<g1::Config>(bases, scalars)
}

/// Compute a multi scalar multiplication for short_weierstrass through
/// arkworks on G2.
pub fn msm_g2(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, ()> {
msm_sw_generic::<g2::Config>(bases, scalars)
}

/// Compute a projective scalar multiplication for short_weierstrass
/// through arkworks on G1.
pub fn mul_projective_g1(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
mul_projective_generic::<g1::Config>(base, scalar)
}

/// Compute a projective scalar multiplication for short_weierstrass
/// through arkworks on G2.
pub fn mul_projective_g2(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
mul_projective_generic::<g2::Config>(base, scalar)
}

#[cfg(test)]
mod tests {
use super::*;
use ark_algebra_test_templates::*;
use ark_ec::{AffineRepr, CurveGroup, Group};
use ark_ff::{fields::Field, One, Zero};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate};
use ark_std::{rand::Rng, test_rng, vec, UniformRand};
use sp_ark_bls12_381::{
fq::Fq, fq2::Fq2, fr::Fr, Bls12_381 as Bls12_381Host, G1Affine as G1AffineHost,
G1Projective as G1ProjectiveHost, G2Affine as G2AffineHost,
G2Projective as G2ProjectiveHost, HostFunctions,
};
use sp_ark_models::pairing::PairingOutput;

#[derive(PartialEq, Eq)]
struct Host;

impl HostFunctions for Host {
fn bls12_381_multi_miller_loop(a: Vec<u8>, b: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_381_multi_miller_loop(a, b)
}
fn bls12_381_final_exponentiation(f12: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_381_final_exponentiation(f12)
}
fn bls12_381_msm_g1(bases: Vec<u8>, bigints: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_381_msm_g1(bases, bigints)
}
fn bls12_381_msm_g2(bases: Vec<u8>, bigints: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_381_msm_g2(bases, bigints)
}
fn bls12_381_mul_projective_g1(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_381_mul_projective_g1(base, scalar)
}
fn bls12_381_mul_projective_g2(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
crate::elliptic_curves::bls12_381_mul_projective_g2(base, scalar)
}
}

type Bls12_381 = Bls12_381Host<Host>;
type G1Projective = G1ProjectiveHost<Host>;
type G2Projective = G2ProjectiveHost<Host>;
type G1Affine = G1AffineHost<Host>;
type G2Affine = G2AffineHost<Host>;

test_group!(g1; G1Projective; sw);
test_group!(g2; G2Projective; sw);
test_group!(pairing_output; PairingOutput<Bls12_381>; msm);
test_pairing!(ark_pairing; super::Bls12_381);

#[test]
fn test_g1_endomorphism_beta() {
assert!(sp_ark_bls12_381::g1::BETA.pow([3u64]).is_one());
}

#[test]
fn test_g1_subgroup_membership_via_endomorphism() {
let mut rng = test_rng();
let generator = G1Projective::rand(&mut rng).into_affine();
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
}

#[test]
fn test_g1_subgroup_non_membership_via_endomorphism() {
let mut rng = test_rng();
loop {
let x = Fq::rand(&mut rng);
let greatest = rng.gen();

if let Some(p) = G1Affine::get_point_from_x_unchecked(x, greatest) {
if !<G1Projective as ark_std::Zero>::is_zero(&p.mul_bigint(Fr::characteristic())) {
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
return
}
}
}
}

#[test]
fn test_g2_subgroup_membership_via_endomorphism() {
let mut rng = test_rng();
let generator = G2Projective::rand(&mut rng).into_affine();
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
}

#[test]
fn test_g2_subgroup_non_membership_via_endomorphism() {
let mut rng = test_rng();
loop {
let x = Fq2::rand(&mut rng);
let greatest = rng.gen();

if let Some(p) = G2Affine::get_point_from_x_unchecked(x, greatest) {
if !<G2Projective as Zero>::is_zero(&p.mul_bigint(Fr::characteristic())) {
assert!(!p.is_in_correct_subgroup_assuming_on_curve());
return
}
}
}
}

// Test vectors and macro adapted from https://github.com/zkcrypto/bls12_381/blob/e224ad4ea1babfc582ccd751c2bf128611d10936/src/test-data/mod.rs
macro_rules! test_vectors {
($projective:ident, $affine:ident, $compress:expr, $expected:ident) => {
let mut e = $projective::zero();

let mut v = vec![];
{
let mut expected = $expected;
for _ in 0..1000 {
let e_affine = $affine::from(e);
let mut serialized = vec![0u8; e.serialized_size($compress)];
e_affine.serialize_with_mode(serialized.as_mut_slice(), $compress).unwrap();
v.extend_from_slice(&serialized[..]);

let mut decoded = serialized;
let len_of_encoding = decoded.len();
(&mut decoded[..]).copy_from_slice(&expected[0..len_of_encoding]);
expected = &expected[len_of_encoding..];
let decoded =
$affine::deserialize_with_mode(&decoded[..], $compress, Validate::Yes)
.unwrap();
assert_eq!(e_affine, decoded);

e += &$projective::generator();
}
}

assert_eq!(&v[..], $expected);
};
}

#[test]
fn g1_compressed_valid_test_vectors() {
let bytes: &'static [u8] = include_bytes!("test-data/g1_compressed_valid_test_vectors.dat");
test_vectors!(G1Projective, G1Affine, Compress::Yes, bytes);
}

#[test]
fn g1_uncompressed_valid_test_vectors() {
let bytes: &'static [u8] =
include_bytes!("test-data/g1_uncompressed_valid_test_vectors.dat");
test_vectors!(G1Projective, G1Affine, Compress::No, bytes);
}

#[test]
fn g2_compressed_valid_test_vectors() {
let bytes: &'static [u8] = include_bytes!("test-data/g2_compressed_valid_test_vectors.dat");
test_vectors!(G2Projective, G2Affine, Compress::Yes, bytes);
}

#[test]
fn g2_uncompressed_valid_test_vectors() {
let bytes: &'static [u8] =
include_bytes!("test-data/g2_uncompressed_valid_test_vectors.dat");
test_vectors!(G2Projective, G2Affine, Compress::No, bytes);
}
}