Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

fairness.gno

2.11 Kb · 61 lines
 1package gnodice
 2
 3import (
 4	"crypto/sha256"
 5	"encoding/binary"
 6	"encoding/hex"
 7	"strconv"
 8)
 9
10// Équité du jeu : empreinte du chiffre caché et calcul du dé.
11// Tout est vérifiable par n'importe qui avec SHA-256 :
12//
13//	empreinte = sha256("gnodice|v1|commit|" + adresse + "|" + chiffre + "|" + secret)
14//	dé        = 1 + (8 premiers octets de sha256("gnodice|v1|roll|" + graine + "|" + empreinte + "|" + numéro)) mod 6
15//
16// Le secret du joueur et la graine du croupier font 32 octets (64 caractères
17// hexadécimaux). Un secret plus court permettrait au croupier de retrouver le
18// chiffre en essayant les 6 possibilités : il est donc refusé.
19
20const hexLen = 64 // 32 octets écrits en hexadécimal
21
22// Commitment calcule l'empreinte d'un chiffre caché. Lecture seule : le site
23// et le croupier peuvent l'appeler pour vérifier leurs calculs.
24func Commitment(player address, guess int, salt string) string {
25	sum := sha256.Sum256([]byte("gnodice|v1|commit|" + player.String() + "|" + strconv.Itoa(guess) + "|" + salt))
26	return hex.EncodeToString(sum[:])
27}
28
29// rollFromSeed calcule le dé à partir de la graine du croupier, de l'empreinte
30// du joueur et du numéro de la partie.
31// Le modulo 6 sur 64 bits a un biais inférieur à 1 sur 3 milliards de milliards :
32// négligeable.
33func rollFromSeed(seed, commitment string, id int64) int {
34	sum := sha256.Sum256([]byte("gnodice|v1|roll|" + seed + "|" + commitment + "|" + itoa64(id)))
35	return int(binary.BigEndian.Uint64(sum[0:8])%DieFaces) + 1
36}
37
38// RollFor : version publique de rollFromSeed, pour que chacun puisse vérifier
39// un tirage passé (graine et empreinte sont publiques après le tirage).
40func RollFor(seed, commitment string, id int64) int {
41	if !isHex64(seed) || !isHex64(commitment) {
42		return 0
43	}
44	return rollFromSeed(seed, commitment, id)
45}
46
47// isHex64 : exactement 64 caractères hexadécimaux minuscules.
48func isHex64(s string) bool {
49	if len(s) != hexLen {
50		return false
51	}
52	for i := 0; i < len(s); i++ {
53		c := s[i]
54		if !(c >= '0' && c <= '9' || c >= 'a' && c <= 'f') {
55			return false
56		}
57	}
58	return true
59}
60
61func itoa64(v int64) string { return strconv.FormatInt(v, 10) }