gsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/security/siphashmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/zh_TW/security/siphashmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/it_IT/security/siphashmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ja_JP/security/siphashmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ko_KR/security/siphashmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/pt_BR/security/siphashmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/sp_SP/security/siphashmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhQ/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/security/siphash.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h#Documentation/security/siphash.rst h]h)}(h"Documentation/security/siphash.rsth]h"Documentation/security/siphash.rst}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h翻译h]h翻译}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhKubj)}(h-张巍 zhangwei h]h)}(h,张巍 zhangwei h](h张巍 zhangwei <}(hj4hhhNhNubh reference)}(hzhangwei@cqsoftware.com.cnh]hzhangwei@cqsoftware.com.cn}(hj>hhhNhNubah}(h]h ]h"]h$]h&]refuri!mailto:zhangwei@cqsoftware.com.cnuh1j<hj4ubh>}(hj4hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj0ubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h1SipHash - 一种短输入伪随机函数(PRF)h]h1SipHash - 一种短输入伪随机函数(PRF)}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1johjlhhhhhK ubh)}(h.:作者: Jason A.Donenfeld h](h:作者: Jason A.Donenfeld <}(hjhhhNhNubj=)}(hjason@zx2c4.comh]hjason@zx2c4.com}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:jason@zx2c4.comuh1j<hjubh>}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjlhhubh)}(hXLSipHash是一种加密安全的伪随机函数,即一种用于生成伪随机密钥的哈 希函数,因为其在处理短输入时表现出色,因此得名。其由密码学家 Daniel J. Bernstein和Jean-Philippe Aumasson设计。目的主要是替 代其他哈希函数,例如:jhash,md5_transform,sha1_transform等。h]hXLSipHash是一种加密安全的伪随机函数,即一种用于生成伪随机密钥的哈 希函数,因为其在处理短输入时表现出色,因此得名。其由密码学家 Daniel J. Bernstein和Jean-Philippe Aumasson设计。目的主要是替 代其他哈希函数,例如:jhash,md5_transform,sha1_transform等。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubh)}(hX"SipHash采用一个完全由随机数生成的密钥,以及一个输入缓冲区或者 多个输入整数,它输出一个与随机数难以区分的整数,你可以将它作 为安全序列、安全cookies的一部分,或者对其进行掩码处理,以便在 哈希表中使用。h]hX"SipHash采用一个完全由随机数生成的密钥,以及一个输入缓冲区或者 多个输入整数,它输出一个与随机数难以区分的整数,你可以将它作 为安全序列、安全cookies的一部分,或者对其进行掩码处理,以便在 哈希表中使用。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjlhhubjk)}(hhh](jp)}(h 生成密钥h]h 生成密钥}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKubh)}(hm密钥应来源于加密安全的随机数生成,要么使用get random bytes 要么使用get random once::h]hl密钥应来源于加密安全的随机数生成,要么使用get random bytes 要么使用get random once:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh literal_block)}(h7siphash_key_t key; get_random_bytes(&key, sizeof(key));h]h7siphash_key_t key; get_random_bytes(&key, sizeof(key));}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubh)}(hH如果你的密钥来源不是这两个,那么你的做法是错的。h]hH如果你的密钥来源不是这两个,那么你的做法是错的。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK"hjhhubeh}(h]id1ah ]h"] 生成密钥ah$]h&]uh1jjhjlhhhhhKubjk)}(hhh](jp)}(h 使用函数h]h 使用函数}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhK%ubh)}(hY这个函数有两个变种,一种是接受整数列表,另一种是接受缓冲区::h]hX这个函数有两个变种,一种是接受整数列表,另一种是接受缓冲区:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK'hjhhubj)}(hDu64 siphash(const void *data, size_t len, const siphash_key_t *key);h]hDu64 siphash(const void *data, size_t len, const siphash_key_t *key);}hj!sbah}(h]h ]h"]h$]h&]hhuh1jhhhK)hjhhubh)}(h和::h]h和:}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK+hjhhubj)}(hXu64 siphash_1u64(u64, const siphash_key_t *key); u64 siphash_2u64(u64, u64, const siphash_key_t *key); u64 siphash_3u64(u64, u64, u64, const siphash_key_t *key); u64 siphash_4u64(u64, u64, u64, u64, const siphash_key_t *key); u64 siphash_1u32(u32, const siphash_key_t *key); u64 siphash_2u32(u32, u32, const siphash_key_t *key); u64 siphash_3u32(u32, u32, u32, const siphash_key_t *key); u64 siphash_4u32(u32, u32, u32, u32, const siphash_key_t *key);h]hXu64 siphash_1u64(u64, const siphash_key_t *key); u64 siphash_2u64(u64, u64, const siphash_key_t *key); u64 siphash_3u64(u64, u64, u64, const siphash_key_t *key); u64 siphash_4u64(u64, u64, u64, u64, const siphash_key_t *key); u64 siphash_1u32(u32, const siphash_key_t *key); u64 siphash_2u32(u32, u32, const siphash_key_t *key); u64 siphash_3u32(u32, u32, u32, const siphash_key_t *key); u64 siphash_4u32(u32, u32, u32, u32, const siphash_key_t *key);}hj=sbah}(h]h ]h"]h$]h&]hhuh1jhhhK-hjhhubh)}(h如果向一个通用的hsiphash函数传递一个恒定长度的常量,他将 在编译的时候将常量折叠,并自动选择一个优化后的函数。h]h如果向一个通用的hsiphash函数传递一个恒定长度的常量,他将 在编译的时候将常量折叠,并自动选择一个优化后的函数。}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hjhhubh)}(h哈希表键函数的用法::h]h哈希表键函数的用法:}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK9hjhhubj)}(hXstruct some_hashtable { DECLARE_HASHTABLE(hashtable, 8); siphash_key_t key; }; void init_hashtable(struct some_hashtable *table) { get_random_bytes(&table->key, sizeof(table->key)); } static inline hlist_head *some_hashtable_bucket(struct some_hashtable *table, struct interesting_input *input) { return &table->hashtable[siphash(input, sizeof(*input), &table->key) & (HASH_SIZE(table->hashtable) - 1)]; }h]hXstruct some_hashtable { DECLARE_HASHTABLE(hashtable, 8); siphash_key_t key; }; void init_hashtable(struct some_hashtable *table) { get_random_bytes(&table->key, sizeof(table->key)); } static inline hlist_head *some_hashtable_bucket(struct some_hashtable *table, struct interesting_input *input) { return &table->hashtable[siphash(input, sizeof(*input), &table->key) & (HASH_SIZE(table->hashtable) - 1)]; }}hjgsbah}(h]h ]h"]h$]h&]hhuh1jhhhK;hjhhubh)}(hK然后,你可以像往常一样对返回的哈希存储桶进行迭代。h]hK然后,你可以像往常一样对返回的哈希存储桶进行迭代。}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhjhhubeh}(h]id2ah ]h"] 使用函数ah$]h&]uh1jjhjlhhhhhK%ubjk)}(hhh](jp)}(h 安全性h]h 安全性}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKMubh)}(hSipHash有着非常高的安全性,因为其有128位的密钥。只要密钥是保密的, 即使攻击者看到多个输出,也无法猜测出函数的正确输出,因为2^128次 方个输出是非常庞大的。h]hSipHash有着非常高的安全性,因为其有128位的密钥。只要密钥是保密的, 即使攻击者看到多个输出,也无法猜测出函数的正确输出,因为2^128次 方个输出是非常庞大的。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKOhjhhubh)}(h'Linux实现了SipHash的“2-4”变体h]h'Linux实现了SipHash的“2-4”变体}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKShjhhubeh}(h]id3ah ]h"] 安全性ah$]h&]uh1jjhjlhhhhhKMubjk)}(hhh](jp)}(hStruct-passing陷阱h]hStruct-passing陷阱}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKVubh)}(hX通常情况下,XuY函数的输出长度不够大,因此你可能需要传递一个预填充 的结构体给SipHash,在这样做时,务必确保结构体没有填充空隙,最简单 的方法就是将结构体的成员按照大小降序的方式排序,并且使用offsetofend() 函数代替sizeof()来获取结构体大小,出于性能的考虑,如果可以的话,最 好将结构体按右边界对齐,示例如下::h]hX通常情况下,XuY函数的输出长度不够大,因此你可能需要传递一个预填充 的结构体给SipHash,在这样做时,务必确保结构体没有填充空隙,最简单 的方法就是将结构体的成员按照大小降序的方式排序,并且使用offsetofend() 函数代替sizeof()来获取结构体大小,出于性能的考虑,如果可以的话,最 好将结构体按右边界对齐,示例如下:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKXhjhhubj)}(hX.const struct { struct in6_addr saddr; u32 counter; u16 dport; } __aligned(SIPHASH_ALIGNMENT) combined = { .saddr = *(struct in6_addr *)saddr, .counter = counter, .dport = dport }; u64 h = siphash(&combined, offsetofend(typeof(combined), dport), &secret);h]hX.const struct { struct in6_addr saddr; u32 counter; u16 dport; } __aligned(SIPHASH_ALIGNMENT) combined = { .saddr = *(struct in6_addr *)saddr, .counter = counter, .dport = dport }; u64 h = siphash(&combined, offsetofend(typeof(combined), dport), &secret);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhK^hjhhubeh}(h]struct-passingah ]h"]struct-passing陷阱ah$]h&]uh1jjhjlhhhhhKVubjk)}(hhh](jp)}(h资源h]h资源}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKjubh)}(he如果你有兴趣了解更多信息,请阅读SipHash论文: https://131002.net/siphash/siphash.pdfh](h?如果你有兴趣了解更多信息,请阅读SipHash论文: }(hjhhhNhNubj=)}(h&https://131002.net/siphash/siphash.pdfh]h&https://131002.net/siphash/siphash.pdf}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1j<hjubeh}(h]h ]h"]h$]h&]uh1hhhhKlhjhhubeh}(h]id4ah ]h"]资源ah$]h&]uh1jjhjlhhhhhKjubeh}(h] siphash-prfah ]h"]1siphash - 一种短输入伪随机函数(prf)ah$]h&]uh1jjhhhhhhhK ubh transition)}(hO-------------------------------------------------------------------------------h]h}(h]h ]h"]h$]h&]uh1j3hhhKohhhhubjk)}(hhh](jp)}(h6HalfSipHash 是 SipHash 的一个较不安全的变种h]h6HalfSipHash 是 SipHash 的一个较不安全的变种}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1johj?hhhhhKsubh)}(h.:作者: Jason A.Donenfeld h](h:作者: Jason A.Donenfeld <}(hjPhhhNhNubj=)}(hjason@zx2c4.comh]hjason@zx2c4.com}(hjXhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:jason@zx2c4.comuh1j<hjPubh>}(hjPhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKuhj?hhubh)}(hX如果你认为SipHash的速度不够快,无法满足你的需求,那么你可以 使用HalfSipHash,这是一种令人担忧但是有用的选择。HalfSipHash 将SipHash的轮数从“2-4”降低到“1-3”,更令人担心的是,它使用一 个容易被穷举攻击的64位密钥(输出为32位),而不是SipHash的128位 密钥,不过,这对于要求高性能“jhash”用户来说这是比较好的选择。h]hX如果你认为SipHash的速度不够快,无法满足你的需求,那么你可以 使用HalfSipHash,这是一种令人担忧但是有用的选择。HalfSipHash 将SipHash的轮数从“2-4”降低到“1-3”,更令人担心的是,它使用一 个容易被穷举攻击的64位密钥(输出为32位),而不是SipHash的128位 密钥,不过,这对于要求高性能“jhash”用户来说这是比较好的选择。}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhj?hhubh)}(h8HalfSipHash是通过 "hsiphash" 系列函数提供的。h]hkey, sizeof(table->key)); } static inline hlist_head *some_hashtable_bucket(struct some_hashtable *table, struct interesting_input *input) { return &table->hashtable[hsiphash(input, sizeof(*input), &table->key) & (HASH_SIZE(table->hashtable) - 1)]; }h]hXstruct some_hashtable { DECLARE_HASHTABLE(hashtable, 8); hsiphash_key_t key; }; void init_hashtable(struct some_hashtable *table) { get_random_bytes(&table->key, sizeof(table->key)); } static inline hlist_head *some_hashtable_bucket(struct some_hashtable *table, struct interesting_input *input) { return &table->hashtable[hsiphash(input, sizeof(*input), &table->key) & (HASH_SIZE(table->hashtable) - 1)]; }}hjisbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjXhhubh)}(hK然后,你可以像往常一样对返回的哈希存储桶进行迭代。h]hK然后,你可以像往常一样对返回的哈希存储桶进行迭代。}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjXhhubeh}(h]id7ah ]h"]哈希表键函数的用法ah$]h&]uh1jjhj?hhhhhKubjk)}(hhh](jp)}(h性能h]h性能}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKubh)}(hhsiphash()大约比jhash()慢三倍,这是因为有许多替换,不过这些都不是问题, 因为哈希表查找不是瓶颈。而且,这些牺牲是为了hsiphash()的安全性和DoS抗 性,这是值得的。h]hhsiphash()大约比jhash()慢三倍,这是因为有许多替换,不过这些都不是问题, 因为哈希表查找不是瓶颈。而且,这些牺牲是为了hsiphash()的安全性和DoS抗 性,这是值得的。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id8ah ]h"]性能ah$]h&]uh1jjhj?hhhhhKubeh}(h]halfsiphash-siphashah ]h"]6halfsiphash 是 siphash 的一个较不安全的变种ah$]h&]uh1jjhhhhhhhKsubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(joN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j0j-jjjjjjjjj(j%jjjjjUjRjjjju nametypes}(j0jjjjj(jjjUjjuh}(j-jljjjjjjjjj%jjj?jjjRjjjXjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages]transform_messages] transformerN include_log]5Documentation/translations/zh_CN/security/siphash.rst(NNNNta decorationNhhub.