blob: 5abf13379842fdecdf60a8d1d0817213010fe15c [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
*/
/**
* @file bls_ietf_ZZZ.h
*
* @author Alexandre Adomnicai
*
* @date December 2022
*
* @brief BLS Header file IETF-compliant according to https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-05
*
*/
#ifndef BLS_IETF_ZZZ_H
#define BLS_IETF_ZZZ_H
#include "pair_ZZZ.h"
#if CURVE_SECURITY_ZZZ == 128
#define SK_LEN 32
#else
#error "IETF-compliant BLS currently only supports 128-bit security level (i.e. BLS12-381)"
#endif
/* Field size is assumed to be greater than or equal to group size */
#define BGS_ZZZ MODBYTES_XXX /**< BLS Group Size */
#define BFS_ZZZ MODBYTES_XXX /**< BLS Field Size */
#define SUCCESS 0x00000000
#define ERR_NULLPOINTER_BLS 0x00000201
#define ERR_BADARGLEN_BLS 0x00000202
#define ERR_BADENCODING_BLS 0x00000203
#define ERR_NOTONCURVE_BLS 0x00000204
#define ERR_BADSIGNATURE_BLS 0x00000205
#define ERR_INVALIDPUBKEY_BLS 0x00000206
#define ERR_BADPOP_BLS 0x00000207
extern const BIG_XXX ISO11_XNUM_BLS381[12]; /**< constants used to compute x_num for the 11-isogeny map for BLS12-381 G1 */
extern const BIG_XXX ISO11_XDEN_BLS381[11]; /**< constants used to compute x_den for the 11-isogeny map for BLS12-381 G1 */
extern const BIG_XXX ISO11_YNUM_BLS381[16]; /**< constants used to compute y_num for the 11-isogeny map for BLS12-381 G1 */
extern const BIG_XXX ISO11_YDEN_BLS381[16]; /**< constants used to compute y_den for the 11-isogeny map for BLS12-381 G1 */
extern const BIG_XXX ISO3_XNUMre_BLS381[4]; /**< constants used to compute x_num for the 3-isogeny map for BLS12-381 G2 */
extern const BIG_XXX ISO3_XNUMim_BLS381[4]; /**< constants used to compute x_num for the 3-isogeny map for BLS12-381 G2 */
extern const BIG_XXX ISO3_XDENre_BLS381[2]; /**< constants used to compute x_den for the 3-isogeny map for BLS12-381 G2 */
extern const BIG_XXX ISO3_XDENim_BLS381[2]; /**< constants used to compute x_den for the 3-isogeny map for BLS12-381 G2 */
extern const BIG_XXX ISO3_YNUMre_BLS381[4]; /**< constants used to compute y_num for the 3-isogeny map for BLS12-381 G2 */
extern const BIG_XXX ISO3_YNUMim_BLS381[4]; /**< constants used to compute y_num for the 3-isogeny map for BLS12-381 G2 */
extern const BIG_XXX ISO3_YDENre_BLS381[3]; /**< constants used to compute y_den for the 3-isogeny map for BLS12-381 G2 */
extern const BIG_XXX ISO3_YDENim_BLS381[3]; /**< constants used to compute y_den for the 3-isogeny map for BLS12-381 G2 */
/* BLS API functions */
/**
* @brief Generation of a BLS secret key according to the RFC draft (Section 2.3).
*
* @param sk Output secret key
* @param ikm Secret input keying material
* @param ikmlen Input keying material length in bytes (>= 32)
* @param salt Salt value
* @param saltlen Salt length in bytes (>= 0)
* @param info Optional octet string (empty string if omitted)
* @param infolen Info length in bytes (>= 0)
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_keygen(char sk[SK_LEN],
const char *ikm, unsigned int ikmlen,
const char *salt, unsigned int saltlen,
const char *info, unsigned int infolen);
/**
* @brief Derivation of a BLS public key in G1 (i.e. minimal-pubkey-size setting)
* from a secret key according to the RFC draft (Section 2.4).
*
* @param pk Output public key
* @param sk Secret key
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_sk_to_pk_G1(ECP_ZZZ *pk, const char *sk);
/**
* @brief Derivation of a BLS public key in G2 (i.e. minimal-sig-size setting)
* from a secret key according to the RFC draft (Section 2.4).
*
* @param pk Output public key
* @param sk Secret key
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_sk_to_pk_G2(ECP2_ZZZ *pk, const char *sk);
/**
* @brief Serialization of a point in G1 into an octet string.
* Same as ECP_ZZZ_toOctet but the order differs to match the Zcash
* serialization format: FP elements are encoded in big-endian format
* (i.e. imaginary|real) while ECP2_ZZZ_toOctet uses little-endian
* (i.e. real|imaginary).
*
* @param bytes Output octet string
* @param point Point in G1
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_serialize_G1(octet *bytes, const ECP_ZZZ *point);
/**
* @brief Serialization of a point in G2 into an octet string.
* Same as ECP_ZZZ_fromOctet but the order differs to match the Zcash
* serialization format: FP elements are encoded in big-endian format
* (i.e. imaginary|real) while ECP_ZZZ_fromOctet uses little-endian
* (i.e. real|imaginary).
*
* @param point Output Point in G1
* @param bytes octet string
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_deserialize_G1(ECP_ZZZ *point, const octet *bytes);
/**
* @brief Serialization of a point in G2 into an octet string.
* Same as ECP2_ZZZ_toOctet but the order differs to match the Zcash
* serialization format: FP elements are encoded in big-endian format
* (i.e. imaginary|real) while ECP2_ZZZ_toOctet uses little-endian
* (i.e. real|imaginary).
*
* @param bytes Output octet string
* @param point Point in G2
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_serialize_G2(octet *bytes, const ECP2_ZZZ *point);
/**
* @brief Deserialization of an octet string into a point in G2.
* Same as ECP2_ZZZ_fromOctet but the order differs to match the Zcash
* serialization format: FP elements are encoded in big-endian format
* (i.e. imaginary|real) while ECP2_ZZZ_fromOctet uses little-endian
* (i.e. real|imaginary).
*
* @param point Output Point in G2
* @param bytes octet string
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_deserialize_G2(ECP2_ZZZ *point, const octet *bytes);
/**
* @brief Compression of a point in G1 into an octet string.
* The most-significant 3 bits are encoded according to ZCash serialization format:
* https://github.com/zkcrypto/pairing/blob/34aa52b0f7bef705917252ea63e5a13fa01af551/src/bls12_381/README.md#serialization
*
* @param bytes Output octet string
* @param point Point in G1
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_compress_G1(octet *bytes, const ECP_ZZZ *point);
/**
* @brief Uncompression of a compressed point in G1.
*
* @param point Output uncompressed point in G1
* @param bytes Compressed point in G1
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_uncompress_G1(ECP_ZZZ *point, const octet *bytes);
/**
* @brief Compression of a point in G2 into an octet string.
* The most-significant 3 bits are encoded according to ZCash serialization format:
* https://github.com/zkcrypto/pairing/blob/34aa52b0f7bef705917252ea63e5a13fa01af551/src/bls12_381/README.md#serialization
*
* @param bytes Output octet string
* @param point Point in G2
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_compress_G2(octet *bytes, const ECP2_ZZZ *point);
/**
* @brief Uncompression of a compressed point in G2.
*
* @param point Output uncompressed point in G2
* @param bytes Compressed point in G2
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_uncompress_G2(ECP2_ZZZ *point, const octet *bytes);
/**
* @brief Hash a byte string into an elliptic curve point on G1 using an uniform encoding type.
*
* @param P Output point
* @param msg Input byte string
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_hash2curve_G1(ECP_ZZZ *P, const octet* msg, const octet* dst);
/**
* @brief Hash a byte string into an elliptic curve point on G1 using a non-uniform encoding type.
*
* @param P Output point
* @param msg Input byte string
* @param dst Domain seperation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_encode2curve_G1(ECP_ZZZ *P, const octet* msg, const octet* dst);
/**
* @brief Hash a byte string into an elliptic curve point on G2 using an uniform encoding type.
*
* @param P Output point
* @param msg Input byte string
* @param dst Domain seperation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_hash2curve_G2(ECP2_ZZZ *P, const octet* msg, const octet* dst);
/**
* @brief Hash a byte string into an elliptic curve point on G2 using a non-uniform encoding type.
*
* @param P Output point
* @param msg Input byte string
* @param dst Domain seperation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_encode2curve_G2(ECP2_ZZZ *P, const octet* msg, const octet* dst);
/**
* @brief Generate a signature in the minimal-signature-size setting. Note that
* the output signature is in the compressed serialization formats as stated in
* https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-05.html#appendix-A.
*
* @param sig Output signature
* @param sk Private key
* @param msg Message to sign
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_core_sign_G1(octet *sig, const char *sk, const octet *msg, const octet *dst);
/**
* @brief Generate a signature in the minimal-pubkey-size setting. Note that
* the output signature is in the compressed serialization formats as stated in
* https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-05.html#appendix-A.
*
* @param sig Output signature
* @param sk Private key
* @param msg Message to sign
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_core_sign_G2(octet *sig, const char *sk, const octet *msg, const octet *dst);
/**
* @brief Verify a signature in the minimal-signature-size setting.
*
* @param sig Signature
* @param pk Public key in G2
* @param msg Signed message
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_core_verify_G1(const octet *sig, const ECP2_ZZZ *PK, const octet *msg, const octet *dst);
/**
* @brief Verify a signature in the minimal-pubkey-size setting.
*
* @param sig Signature
* @param pk Public key in G1
* @param msg Signed message
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_core_verify_G2(const octet *sig, const ECP_ZZZ *PK, const octet *msg, const octet *dst);
/**
* @brief Aggregate multiple signatures into a single one in the minimal-signature-size setting.
* Note that the output signature is in the compressed serialization formats as stated in
* https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-05.html#appendix-A.
*
* @param out Output signature
* @param in Input signatures to aggregate
* @param n Number of input signatures
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_aggregate_G1(octet *out, const octet *in, unsigned int n);
/**
* @brief Aggregate multiple signatures into a single one in the minimal-pubkey-size setting.
* Note that the output signature is in the compressed serialization formats as stated in
* https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-05.html#appendix-A.
*
* @param out Output signature
* @param in Input signatures to aggregate
* @param n Number of input signatures
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_aggregate_G2(octet *out, const octet *in, unsigned int n);
/**
* @brief Verify an aggregated signature in the minimal-signature-size setting.
*
* @param sig Aggregated signature
* @param pk Public keys in G2
* @param msg Signed messages
* @param n Number of public keys/messages
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_core_aggregate_verify_G1(const octet *sig, const ECP2_ZZZ PK[], const octet msg[], unsigned int n, const octet *dst);
/**
* @brief Verify an aggregated signature in the minimal-pubkey-size setting.
*
* @param sig Aggregated signature
* @param pk Public keys in G1
* @param msg Signed messages
* @param n Number of public keys/messages
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_core_aggregate_verify_G2(const octet *sig, const ECP_ZZZ PK[], const octet msg[], unsigned int n, const octet *dst);
/**
* @brief Generate a proof of possession (POP) for a given secret key in the
* minimal-sig-size setting.
*
* @param proof Output proof of possession
* @param sk Secret key
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_pop_prove_G1(octet *proof, const char *sk);
/**
* @brief Generate a proof of possession (POP) for a given secret key in the
* minimal-pubkey-size setting.
*
* @param proof Output proof of possession
* @param sk Secret key
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_pop_prove_G2(octet *proof, const char *sk);
/**
* @brief Verify a proof of possession and its corresponding public key in the
* minimal-sig-size setting.
*
* @param proof Proof of possession
* @param PK Public key associated to the proof of possession
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_pop_verify_G1(const octet *proof, const ECP2_ZZZ *PK);
/**
* @brief Verify a proof of possession and its corresponding public key in the
* minimal-pubkey-size setting.
*
* @param proof Proof of possession
* @param PK Public key associated to the proof of possession
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_pop_verify_G2(const octet *proof, const ECP_ZZZ *PK);
/**
* @brief Verify an aggregated signature of the same message under different
* public keys in the minimal-sig-size setting.
* Note it is the responsibility of the caller that all public keys passed as
* arguments to this algorithm MUST have a corresponding proof of possession,
* and the result of evaluating PopVerify on each public key and its proof MUST
* be VALID.
*
* @param sig Aggregated signature
* @param pk Public keys in G2
* @param msg Signed message
* @param n Number of public keys
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_fast_aggregate_verify_G1(const octet *sig, const ECP2_ZZZ PK[], const octet *msg, unsigned int n, const octet *dst);
/**
* @brief Verify an aggregated signature of the same message under different
* public keys in the minimal-pubkey-size setting.
* Note it is the responsibility of the caller that all public keys passed as
* arguments to this algorithm MUST have a corresponding proof of possession,
* and the result of evaluating PopVerify on each public key and its proof MUST
* be VALID.
*
* @param sig Aggregated signature
* @param pk Public keys in G1
* @param msg Signed message
* @param n Number of public keys
* @param dst Domain separation tag
*
* @return 0 if successful, error code otherwise
*/
int BLS_IETF_ZZZ_fast_aggregate_verify_G2(const octet *sig, const ECP_ZZZ PK[], const octet *msg, unsigned int n, const octet *dst);
#endif