Skip to content

Commit 81b1f98

Browse files
authored
Merge pull request ethereum#25 from zama-ai/petar/verify-zkpok
Add support for ciphertext verification
2 parents 982613e + 831f55c commit 81b1f98

File tree

1 file changed

+47
-15
lines changed

1 file changed

+47
-15
lines changed

core/vm/contracts.go

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,11 @@ type tomlConfigOptions struct {
12581258
Mode string
12591259
OracleDBAddress string
12601260
}
1261+
1262+
Zk struct {
1263+
Verify bool
1264+
VerifyRPCAddress string
1265+
}
12611266
}
12621267

12631268
var tomlConfig tomlConfigOptions
@@ -1285,7 +1290,8 @@ func generateEd25519Keys() error {
12851290
return nil
12861291
}
12871292

1288-
var httpClient http.Client = http.Client{}
1293+
var requireHttpClient http.Client = http.Client{}
1294+
var zkHttpClient http.Client = http.Client{}
12891295

12901296
var publicSignatureKey []byte
12911297
var privateSignatureKey []byte
@@ -1503,7 +1509,7 @@ func fheEncryptToNetworkKey(value uint64) ([]byte, error) {
15031509
return ctBytes, nil
15041510
}
15051511

1506-
func fheEncryptToUserKey(value uint64, userAddress common.Address) (ret []byte, err error) {
1512+
func fheEncryptToUserKey(value uint64, userAddress common.Address) ([]byte, error) {
15071513
if value > 15 {
15081514
return nil, errors.New("input must be less than 15")
15091515
}
@@ -1543,13 +1549,39 @@ func (e *verifyCiphertext) RequiredGas(input []byte) uint64 {
15431549
return 8
15441550
}
15451551

1546-
func (e *verifyCiphertext) Run(accessibleState PrecompileAccessibleState, caller common.Address, addr common.Address, input []byte, readOnly bool) (ret []byte, err error) {
1547-
const CiphertextSize = 65544
1548-
1549-
// TODO: Verify proof.
1550-
// For testing: If input size <= `CiphertextSize`, treat the whole input as ciphertext.
1551-
ciphertext := input[0:minInt(CiphertextSize, len(input))]
1552+
func verifyZkProof(input []byte) ([]byte, error) {
1553+
req, err := http.NewRequest(http.MethodPost, tomlConfig.Zk.VerifyRPCAddress, bytes.NewReader(input))
1554+
if err != nil {
1555+
return nil, err
1556+
}
1557+
req.Header.Add("Content-Type", "application/msgpack")
1558+
resp, err := zkHttpClient.Do(req)
1559+
if err != nil {
1560+
return nil, err
1561+
}
1562+
if resp.StatusCode != 200 {
1563+
return nil, fmt.Errorf("failure HTTP status code on ZK verify: %d", resp.StatusCode)
1564+
}
1565+
body, err := ioutil.ReadAll(resp.Body)
1566+
if err != nil {
1567+
return nil, errors.New("failed reading ZK verification response body")
1568+
}
1569+
return body, nil
1570+
}
15521571

1572+
func (e *verifyCiphertext) Run(accessibleState PrecompileAccessibleState, caller common.Address, addr common.Address, input []byte, readOnly bool) ([]byte, error) {
1573+
var ciphertext []byte
1574+
if !tomlConfig.Zk.Verify {
1575+
// For testing: If input size <= `CiphertextSize`, treat the whole input as ciphertext.
1576+
const CiphertextSize = 65544
1577+
ciphertext = input[0:minInt(CiphertextSize, len(input))]
1578+
} else {
1579+
var err error
1580+
ciphertext, err = verifyZkProof(input)
1581+
if err != nil {
1582+
return nil, err
1583+
}
1584+
}
15531585
ctHash := crypto.Keccak256Hash(ciphertext)
15541586
accessibleState.Interpreter().verifiedCiphertexts[ctHash] = &verifiedCiphertext{accessibleState.Interpreter().evm.depth, ciphertext}
15551587
return ctHash.Bytes(), nil
@@ -1558,13 +1590,13 @@ func (e *verifyCiphertext) Run(accessibleState PrecompileAccessibleState, caller
15581590
// Return a memory with a layout that matches the `bytes` EVM type, namely:
15591591
// - 32 byte integer in big-endian order as length
15601592
// - the actual bytes in the `bytes` value
1561-
func toEVMBytes(input []byte) (ret []byte) {
1593+
func toEVMBytes(input []byte) []byte {
15621594
len := uint64(len(input))
15631595
lenBytes32 := uint256.NewInt(len).Bytes32()
1564-
ret = make([]byte, 0, len+32)
1596+
ret := make([]byte, 0, len+32)
15651597
ret = append(ret, lenBytes32[:]...)
15661598
ret = append(ret, input...)
1567-
return
1599+
return ret
15681600
}
15691601

15701602
type reencrypt struct{}
@@ -1646,12 +1678,12 @@ func putRequire(ciphertext []byte, value bool) error {
16461678
if err != nil {
16471679
return err
16481680
}
1649-
resp, err := httpClient.Do(req)
1681+
resp, err := requireHttpClient.Do(req)
16501682
if err != nil {
16511683
return err
16521684
}
16531685
if resp.StatusCode != 200 {
1654-
return fmt.Errorf("failure HTTP status code: %d", resp.StatusCode)
1686+
return fmt.Errorf("failure HTTP status code on require PUT: %d", resp.StatusCode)
16551687
}
16561688
return nil
16571689
}
@@ -1662,12 +1694,12 @@ func getRequire(ciphertext []byte) (bool, error) {
16621694
if err != nil {
16631695
return false, nil
16641696
}
1665-
resp, err := httpClient.Do(req)
1697+
resp, err := requireHttpClient.Do(req)
16661698
if err != nil {
16671699
return false, err
16681700
}
16691701
if resp.StatusCode != 200 {
1670-
return false, fmt.Errorf("failure HTTP status code: %d", resp.StatusCode)
1702+
return false, fmt.Errorf("require: failure HTTP status code on require GET: %d", resp.StatusCode)
16711703
}
16721704
body, err := ioutil.ReadAll(resp.Body)
16731705
if err != nil {

0 commit comments

Comments
 (0)