mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-26 08:35:17 +00:00
156 lines
3.5 KiB
Go
156 lines
3.5 KiB
Go
|
/*
|
||
|
* Copyright (c) 2012-2020 MIRACL UK Ltd.
|
||
|
*
|
||
|
* This file is part of MIRACL Core
|
||
|
* (see https://github.com/miracl/core).
|
||
|
*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
/* Boneh-Lynn-Shacham signature 256-bit API Functions */
|
||
|
|
||
|
/* Loosely (for now) following https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-02 */
|
||
|
|
||
|
// Minimal-signature-size variant
|
||
|
|
||
|
package bls48581
|
||
|
|
||
|
import "source.quilibrium.com/quilibrium/ceremonyclient/ec/bls48581/core"
|
||
|
|
||
|
//import "fmt"
|
||
|
|
||
|
const BFS int = int(MODBYTES)
|
||
|
const BGS int = int(MODBYTES)
|
||
|
const BLS_OK int = 0
|
||
|
const BLS_FAIL int = -1
|
||
|
|
||
|
var G2_TAB []*FP16
|
||
|
|
||
|
func ceil(a int, b int) int {
|
||
|
return (((a)-1)/(b) + 1)
|
||
|
}
|
||
|
|
||
|
/* output u \in F_p */
|
||
|
func hash_to_field(hash int, hlen int, DST []byte, M []byte, ctr int) []*FP {
|
||
|
q := NewBIGints(Modulus)
|
||
|
nbq := q.nbits()
|
||
|
L := ceil(nbq+AESKEY*8, 8)
|
||
|
var u []*FP
|
||
|
var fd = make([]byte, L)
|
||
|
OKM := core.XMD_Expand(hash, hlen, L*ctr, DST, M)
|
||
|
|
||
|
for i := 0; i < ctr; i++ {
|
||
|
for j := 0; j < L; j++ {
|
||
|
fd[j] = OKM[i*L+j]
|
||
|
}
|
||
|
u = append(u, NewFPbig(DBIG_fromBytes(fd).ctmod(q, uint(8*L-nbq))))
|
||
|
}
|
||
|
return u
|
||
|
}
|
||
|
|
||
|
/* hash a message to an ECP point, using SHA2, random oracle method */
|
||
|
func bls256_hash_to_point(M []byte) *ECP {
|
||
|
DST := []byte("BLS_SIG_BLS48581G1_XMD:SHA-512_SVDW_RO_NUL_")
|
||
|
u := hash_to_field(core.MC_SHA2, HASH_TYPE, DST, M, 2)
|
||
|
|
||
|
P := ECP_map2point(u[0])
|
||
|
P1 := ECP_map2point(u[1])
|
||
|
P.Add(P1)
|
||
|
P.Cfp()
|
||
|
P.Affine()
|
||
|
return P
|
||
|
}
|
||
|
|
||
|
func Init() int {
|
||
|
G := ECP8_generator()
|
||
|
if G.Is_infinity() {
|
||
|
return BLS_FAIL
|
||
|
}
|
||
|
G2_TAB = precomp(G)
|
||
|
return BLS_OK
|
||
|
}
|
||
|
|
||
|
/* generate key pair, private key S, public key W */
|
||
|
func KeyPairGenerate(IKM []byte, S []byte, W []byte) int {
|
||
|
r := NewBIGints(CURVE_Order)
|
||
|
nbr := r.nbits()
|
||
|
L := ceil(3*ceil(nbr, 8), 2)
|
||
|
LEN := core.InttoBytes(L, 2)
|
||
|
AIKM := make([]byte, len(IKM)+1)
|
||
|
for i := 0; i < len(IKM); i++ {
|
||
|
AIKM[i] = IKM[i]
|
||
|
}
|
||
|
AIKM[len(IKM)] = 0
|
||
|
|
||
|
G := ECP8_generator()
|
||
|
if G.Is_infinity() {
|
||
|
return BLS_FAIL
|
||
|
}
|
||
|
SALT := []byte("BLS-SIG-KEYGEN-SALT-")
|
||
|
PRK := core.HKDF_Extract(core.MC_SHA2, HASH_TYPE, SALT, AIKM)
|
||
|
OKM := core.HKDF_Expand(core.MC_SHA2, HASH_TYPE, L, PRK, LEN)
|
||
|
|
||
|
dx := DBIG_fromBytes(OKM[:])
|
||
|
s := dx.ctmod(r, uint(8*L-nbr))
|
||
|
s.ToBytes(S)
|
||
|
// SkToPk
|
||
|
G = G2mul(G, s)
|
||
|
G.ToBytes(W, true)
|
||
|
return BLS_OK
|
||
|
}
|
||
|
|
||
|
/* Sign message m using private key S to produce signature SIG */
|
||
|
func Core_Sign(SIG []byte, M []byte, S []byte) int {
|
||
|
D := bls256_hash_to_point(M)
|
||
|
s := FromBytes(S)
|
||
|
D = G1mul(D, s)
|
||
|
D.ToBytes(SIG, true)
|
||
|
return BLS_OK
|
||
|
}
|
||
|
|
||
|
/* Verify signature given message M, the signature SIG, and the public key W */
|
||
|
|
||
|
func Core_Verify(SIG []byte, M []byte, W []byte) int {
|
||
|
HM := bls256_hash_to_point(M)
|
||
|
|
||
|
D := ECP_fromBytes(SIG)
|
||
|
if !G1member(D) {
|
||
|
return BLS_FAIL
|
||
|
}
|
||
|
D.Neg()
|
||
|
|
||
|
PK := ECP8_fromBytes(W)
|
||
|
if !G2member(PK) {
|
||
|
return BLS_FAIL
|
||
|
}
|
||
|
|
||
|
// Use new multi-pairing mechanism
|
||
|
r := Initmp()
|
||
|
Another_pc(r, G2_TAB, D)
|
||
|
Another(r, PK, HM)
|
||
|
v := Miller(r)
|
||
|
|
||
|
//.. or alternatively
|
||
|
// G := ECP8_generator()
|
||
|
// if G.Is_infinity() {return BLS_FAIL}
|
||
|
// v := Ate2(G, D, PK, HM)
|
||
|
|
||
|
v = Fexp(v)
|
||
|
|
||
|
if v.Isunity() {
|
||
|
return BLS_OK
|
||
|
} else {
|
||
|
return BLS_FAIL
|
||
|
}
|
||
|
}
|