ceremonyclient/ec/bls48581/BLS256.go
2023-04-15 00:05:26 -04:00

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
}
}