// Copyright (c) 2016 The Zcash developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "prf.h" #include "crypto/sha256.h" uint256 PRF(bool a, bool b, bool c, bool d, const uint252& x, const uint256& y) { uint256 res; unsigned char blob[64]; memcpy(&blob[0], x.begin(), 32); memcpy(&blob[32], y.begin(), 32); blob[0] &= 0x0F; blob[0] |= (a ? 1 << 7 : 0) | (b ? 1 << 6 : 0) | (c ? 1 << 5 : 0) | (d ? 1 << 4 : 0); CSHA256 hasher; hasher.Write(blob, 64); hasher.FinalizeNoPadding(res.begin()); return res; } uint256 PRF_addr(const uint252& a_sk, unsigned char t) { uint256 y; *(y.begin()) = t; return PRF(1, 1, 0, 0, a_sk, y); } uint256 PRF_addr_a_pk(const uint252& a_sk) { return PRF_addr(a_sk, 0); } uint256 PRF_addr_sk_enc(const uint252& a_sk) { return PRF_addr(a_sk, 1); } uint256 PRF_nf(const uint252& a_sk, const uint256& rho) { return PRF(1, 1, 1, 0, a_sk, rho); } uint256 PRF_pk(const uint252& a_sk, size_t i0, const uint256& h_sig) { if ((i0 != 0) && (i0 != 1)) { throw std::domain_error("PRF_pk invoked with index out of bounds"); } return PRF(0, i0, 0, 0, a_sk, h_sig); } uint256 PRF_rho(const uint252& phi, size_t i0, const uint256& h_sig) { if ((i0 != 0) && (i0 != 1)) { throw std::domain_error("PRF_rho invoked with index out of bounds"); } return PRF(0, i0, 1, 0, phi, h_sig); }