pseudorandom และสุ่มตัวเลขแตกต่างกันอย่างแท้จริงอย่างไรและทำไมจึงมีความสำคัญ?


665

ฉันไม่เคยได้รับสิ่งนี้เลย เพียงแค่พูดว่าคุณเขียนโปรแกรมเล็ก ๆ ในภาษาใดก็ได้ที่หมุนลูกเต๋าบางส่วน (เพียงใช้ลูกเต๋าเป็นตัวอย่าง) หลังจาก 600,000 ม้วนแต่ละหมายเลขจะถูกม้วนประมาณ 100,000 ครั้งซึ่งเป็นสิ่งที่ฉันคาดหวัง

ทำไมถึงมีเว็บไซต์ที่ทุ่มเทให้กับ 'การสุ่มอย่างแท้จริง'? แน่นอนว่าจากการสังเกตข้างต้นโอกาสที่จะได้รับหมายเลขใด ๆ นั้นมีค่าเกือบ 1 ว่ามีกี่หมายเลขที่สามารถเลือกได้

ฉันลองใช้Python : นี่คือผลลัพธ์ของม้วน 60 ล้าน ความแปรปรวนสูงสุดเท่ากับ 0.15 ไม่ว่าจะเป็นแบบสุ่มที่จะได้รับ?

1 - 9997653 2347.0
2 - 9997789 2211.0
3 - 9996853 3147.0
4 - 10006533 -6533.0
5 - 10002774 -2774.0
6 - 9998398 1602.0

1
ลองดูที่บทความของวิกิพีเดียเกี่ยวกับฮาร์ดแวร์ที่สร้างตัวเลขสุ่มดูได้ที่ - stats.stackexchange.com/questions/32794/…
steadyfish

21
คุณหมายถึงอะไรโดย "ทอยลูกเต๋า"? มีแขนหุ่นยนต์และกล้องติดอยู่หรือไม่?
starblue

3
ในขณะที่ฉันเห็นด้วยกับแก่นสารทั่วไปของน้ำเสียงของคุณเรามักจะกังวลเกี่ยวกับเรื่องนี้มากเกินไป แต่มันถูกเอาเปรียบในชีวิตจริง: en.wikipedia.org/wiki/Ronald_Dale_Harris
ผู้เล่นเกรดี้

3
ดูนี้บทความเกี่ยวกับเกมโป๊กเกอร์ออนไลน์ที่ขาดหายไปตามบุญตามกรรมที่แท้จริงว่าทำไมมันเป็นเรื่องสำคัญ
Varaquilex

1
หากคุณวางเคาน์เตอร์ 0-5 และหมุนลูกเต๋า 666 ล้านล้านครั้งคุณก็จะได้การแจกแจงที่เท่าเทียมกัน
jcora

คำตอบ:


1384

มาเล่นโป๊กเกอร์คอมพิวเตอร์กันเถอะแค่คุณฉันและเซิร์ฟเวอร์ที่เราทั้งคู่ไว้วางใจ เซิร์ฟเวอร์ใช้ตัวสร้างตัวเลขสุ่มหลอกซึ่งเริ่มต้นด้วยเมล็ด 32 บิตก่อนที่เราจะเล่น ดังนั้นจึงมีดาดฟ้าที่เป็นไปได้ประมาณสี่พันล้านชั้น

ฉันได้ไพ่ห้าใบในมือ - ดูเหมือนว่าเราไม่ได้เล่น Texas Hold 'Em สมมติว่าไพ่ถูกแจกให้ฉันหนึ่งใบกับคุณหนึ่งใบกับฉันหนึ่งใบให้กับคุณและอื่น ๆ ดังนั้นฉันมีไพ่ใบที่หนึ่ง, สาม, ห้า, เจ็ดและเก้าในสำรับ

ก่อนหน้านี้ฉันใช้ตัวสร้างตัวเลขสุ่มหลอกสี่พันล้านครั้งต่อหนึ่งเมล็ดและเขียนการ์ดใบแรกที่สร้างขึ้นสำหรับแต่ละการ์ดลงในฐานข้อมูล สมมติว่าไพ่ใบแรกของฉันคือราชินีแห่งโพดำ นั่นแสดงให้เห็นเพียงใบเดียวว่าเป็นบัตรใบแรกในหนึ่งใบในทุก ๆ 52 ของสำรับที่เป็นไปได้ดังนั้นเราจึงลดจำนวนสำรับที่เป็นไปได้จากสี่พันล้านเป็นประมาณ 80 ล้านหรือมากกว่านั้น

สมมติว่าไพ่ใบที่สองของฉันคือหัวใจทั้งสาม ตอนนี้ฉันใช้ RNG ของฉัน 80 ล้านครั้งโดยใช้เมล็ด 80 ล้านที่ผลิตราชินีแห่งโพดำเป็นหมายเลขแรก ใช้เวลาสองสามวินาที ฉันจดทุกสำรับที่สร้างหัวใจทั้งสามเป็นไพ่ใบที่สาม - ไพ่ใบที่สองในมือของฉัน นั่นเป็นเพียงประมาณ 2% ของดาดฟ้าดังนั้นตอนนี้เราลงไปถึง 2 ล้านชั้น

สมมติว่าไพ่ใบที่สามในมือของฉันคือ 7 ของสโมสร ฉันมีฐานข้อมูล 2 ล้านเมล็ดที่แจกไพ่สองใบของฉัน ฉันใช้ RNG ของฉันอีก 2 ล้านครั้งเพื่อค้นหา 2% ของเด็คเหล่านั้นที่ผลิต 7 ของคลับเป็นการ์ดใบที่สามและเราลงเหลือเพียง 40,000 เด็ค

คุณเห็นว่าสิ่งนี้เกิดขึ้นได้อย่างไร ฉันวิ่ง RNG ของฉัน 40000 ครั้งเพื่อหาเมล็ดทั้งหมดที่ผลิตไพ่ใบที่สี่ของฉันและนั่นทำให้เราลงไปที่ 800 ชั้นจากนั้นเรียกใช้อีก 800 ครั้งเพื่อรับเมล็ด ~ 20 ที่ผลิตไพ่ใบที่ห้าของฉันและตอนนี้ฉันแค่ สร้างไพ่ยี่สิบสำรับเหล่านั้นและฉันรู้ว่าคุณมีหนึ่งในยี่สิบมือที่เป็นไปได้ ยิ่งกว่านั้นฉันมีความคิดที่ดีมากเกี่ยวกับสิ่งที่ฉันจะวาดต่อไป

ตอนนี้คุณเห็นหรือไม่ว่าทำไมการสุ่มตัวอย่างที่แท้จริงจึงสำคัญ วิธีที่คุณอธิบายคุณคิดว่าการกระจายนั้นสำคัญ แต่การกระจายไม่ใช่สิ่งที่ทำให้กระบวนการสุ่ม ความไม่แน่นอนคือสิ่งที่ทำให้กระบวนการสุ่ม

UPDATE

จากความคิดเห็น (ตอนนี้ถูกลบเนื่องจากความไม่เป็นธรรม) พวกเขาอย่างน้อย 0.3% ของผู้ที่เคยอ่านสิ่งนี้จะสับสนในประเด็นของฉัน เมื่อผู้คนโต้เถียงกับจุดที่ฉันไม่ได้ทำหรือแย่กว่านั้นโต้เถียงกับจุดที่ฉันได้ทำบนสมมติฐานที่ว่าฉันไม่ได้ทำให้พวกเขาแล้วฉันรู้ว่าฉันต้องอธิบายให้ชัดเจนยิ่งขึ้นและระมัดระวัง

ดูเหมือนจะมีความสับสนเป็นพิเศษเกี่ยวกับการกระจายคำดังนั้นฉันจึงต้องการเรียกใช้การอย่างระมัดระวัง

คำถามในมือคือ:

  • ตัวเลขหลอกเทียมและตัวเลขสุ่มแตกต่างกันอย่างไร
  • ทำไมความแตกต่างจึงสำคัญ
  • ความแตกต่างมีบางอย่างเกี่ยวกับการกระจายเอาต์พุตของ PRNG หรือไม่?

เริ่มต้นด้วยการพิจารณาวิธีที่สมบูรณ์แบบในการสร้างไพ่สำรับสุ่มที่เล่นโป๊กเกอร์ จากนั้นเราจะดูว่าเทคนิคอื่น ๆ สำหรับการสร้างเด็คแตกต่างกันอย่างไรและถ้าเป็นไปได้ที่จะใช้ประโยชน์จากความแตกต่าง

TRNGขอเริ่มต้นด้วยการสมมติว่าเราได้กล่องวิเศษที่มีป้ายกำกับ เมื่ออินพุตของมันเราให้จำนวนเต็ม n มากกว่าหรือเท่ากับหนึ่งและเป็นผลลัพธ์มันให้ตัวเลขสุ่มอย่างแท้จริงระหว่างหนึ่งถึง n รวม เอาท์พุทของกล่องนั้นคาดเดาไม่ได้อย่างสมบูรณ์ (เมื่อได้รับตัวเลขอื่นที่ไม่ใช่หนึ่ง) และตัวเลขใด ๆ ระหว่างหนึ่งและ n มีโอกาสเป็นอื่น ที่จะบอกว่าการจัดจำหน่ายเป็นชุด (มีการตรวจสอบทางสถิติขั้นสูงอื่น ๆ เพิ่มเติมของการสุ่มที่เราสามารถทำได้; ฉันไม่สนใจจุดนี้เพราะมันไม่ใช่สิ่งที่ขัดแย้งกับข้อโต้แย้งของฉัน TRNG นั้นสุ่มอย่างสมบูรณ์ทางสถิติโดยการสันนิษฐาน)

เราเริ่มต้นด้วยสำรับไพ่ที่ไม่มีการสับ เราถามกล่องถึงตัวเลขระหว่างหนึ่งถึง 52 นั่นคือ, TRNG(52). ไม่ว่าจะให้เบอร์ใดเราก็นับจำนวนไพ่ที่ได้จากการเรียงไพ่ของเราและนำการ์ดนั้นออก มันจะกลายเป็นไพ่ใบแรกในสำรับสับไพ่ จากนั้นเราจะขอTRNG(51)และทำเช่นเดียวกันเพื่อเลือกไพ่ใบที่สองเป็นต้น

อีกวิธีในการดูคือ: มี 52! = 52 x 51 x 50 ... x 2 x 1 ชั้นเป็นไปได้ซึ่งเป็นประมาณ 2 226 เราได้เลือกหนึ่งในนั้นโดยการสุ่มอย่างแท้จริง

ตอนนี้เราแจกการ์ด เมื่อฉันดูไพ่ฉันไม่รู้ว่าการ์ดอะไรที่คุณมี (นอกเหนือจากความจริงที่ชัดเจนว่าคุณไม่มีการ์ดใด ๆ ที่ฉันมี) พวกเขาอาจเป็นการ์ดใดก็ได้โดยมีความน่าจะเป็นเท่ากัน

ขอผมอธิบายให้ชัดเจนนะ ขณะนี้มีการกระจายสม่ำเสมอของการส่งออกของแต่ละบุคคลของTRNG(n); แต่ละอันเลือกตัวเลขระหว่าง 1 ถึง n โดยมีความน่าจะเป็น 1 / n นอกจากนี้ผลลัพธ์ของกระบวนการนี้ก็คือเราได้เลือกหนึ่งใน 52! ชั้นไปได้ด้วยความน่าจะเป็นของ 1/52 !, เพื่อการจัดจำหน่ายที่มากกว่าชุดของชั้นที่เป็นไปได้คือยังเครื่องแบบ

เอาล่ะ

PRNGตอนนี้ขอสมมติว่าเรามีกล่องวิเศษน้อยที่มีป้ายกำกับ ก่อนที่คุณจะสามารถใช้งานได้นั้นจะต้องได้เมล็ดมีจำนวนที่ไม่ได้ลงชื่อ 32 บิต

นอกเหนือ: ทำไม 32 ? ไม่สามารถทำการเพาะด้วยหมายเลข 64- หรือ 256- หรือ 10,000- บิต? แน่ใจ แต่ในทางปฏิบัติ (1) PRNG ส่วนใหญ่นั้นมีจำนวน 32 บิตและ (2) ถ้าคุณมีการสุ่ม 10,000 บิตเพื่อสร้างเมล็ดแล้วทำไมคุณถึงใช้ PRNG เลย? คุณมีแหล่งสุ่ม 10,000 บิตอยู่แล้ว!

อย่างไรก็ตามกลับไปที่วิธีการทำงานของ PRNG: TRNGหลังจากที่มีเมล็ดคุณสามารถใช้วิธีเดียวกันกับที่คุณใช้ นั่นคือคุณผ่านตัวเลข n และมันให้ตัวเลขกลับคืนระหว่าง 1 ถึง n รวม นอกจากนี้การกระจายตัวของการส่งออกว่าจะมากหรือน้อยเครื่องแบบ นั่นคือเมื่อเราขอPRNGตัวเลขระหว่าง 1 ถึง 6 เราจะได้ 1, 2, 3, 4, 5 หรือ 6 แต่ละครั้งประมาณหนึ่งในหกของเวลาไม่ว่าเมล็ดจะเป็นอะไรก็ตาม

ฉันต้องการเน้นจุดนี้หลายครั้งเพราะดูเหมือนว่าเป็นสิ่งที่ทำให้ผู้แสดงความคิดเห็นบางคนสับสน การกระจายตัวของ PRNG นั้นเหมือนกันอย่างน้อยสองวิธี อันดับแรกสมมติว่าเราเลือกเมล็ดเฉพาะ เราคาดหวังว่าลำดับPRNG(6), PRNG(6), PRNG(6)...ต่อล้านครั้งจะทำให้เกิดการกระจายตัวของตัวเลขอย่างสม่ำเสมอระหว่าง 1 ถึง 6 และสองถ้าเราเลือกเมล็ดที่แตกต่างกันหนึ่งล้านเมล็ดและเรียกPRNG(6) หนึ่งครั้งสำหรับแต่ละเมล็ด 6. สม่ำเสมอของ PRNG ทั่วทั้งของการดำเนินงานเหล่านี้ไม่ได้เกี่ยวข้องกับการโจมตีฉันกำลังอธิบาย

กระบวนการนี้มีการกล่าวถึงว่าเป็นการหลอกแบบสุ่มเพราะพฤติกรรมของกล่องนั้นเป็นสิ่งที่กำหนดอย่างแท้จริง มันเลือกจากหนึ่งใน 2 32พฤติกรรมที่เป็นไปได้ขึ้นอยู่กับเมล็ด นั่นคือเมื่อมันเมล็ดPRNG(6), PRNG(6), PRNG(6), ... ผลิตลำดับของตัวเลขที่มีการกระจายชุด แต่ลำดับที่ทั้งหมดถูกกำหนดโดยเมล็ด สำหรับลำดับการโทรที่กำหนดให้พูด PRNG (52), PRNG (51) ... และอื่น ๆ มีเพียง 2 32ลำดับที่เป็นไปได้ เมล็ดเป็นหลักเลือกที่เราจะได้รับ

เพื่อสร้างเด็คในขณะนี้เซิร์ฟเวอร์สร้างเมล็ด (ได้อย่างไรเราจะกลับมาที่จุดนั้น) จากนั้นพวกเขาก็โทรPRNG(52)มาPRNG(51)และอื่น ๆ เพื่อสร้างสำรับคล้ายกับก่อนหน้านี้

ระบบนี้ไวต่อการโจมตีที่ฉันอธิบาย ในการโจมตีเซิร์ฟเวอร์ก่อนอื่นให้เราคัดลอกสำเนาของกล่องของเราด้วย 0 และขอPRNG(52)และเขียนลงไป จากนั้นเราก็เติมเมล็ดด้วย 1 ขอPRNG(52)และเขียนลงไปจนถึง 2 32 -1

ทีนี้เซิร์ฟเวอร์โปกเกอร์ที่ใช้ PRNG ในการสร้างเด็คต้องทำการสร้างเมล็ดอย่างใด มันไม่สำคัญว่าพวกเขาจะทำเช่นนั้นได้อย่างไร พวกเขาสามารถเรียกTRNG(2^32)เพื่อให้ได้เมล็ดสุ่มอย่างแท้จริง หรือพวกเขาอาจใช้เวลาปัจจุบันเป็นเมล็ดพันธุ์ซึ่งแทบจะไม่สุ่มเลย ฉันรู้ว่าเวลาเท่าไหร่ที่คุณทำ จุดของการโจมตีของฉันก็คือว่ามันไม่สำคัญเพราะฉันมีฐานข้อมูลของฉัน เมื่อฉันเห็นการ์ดใบแรกของฉันฉันสามารถกำจัด 98% ของเมล็ดที่เป็นไปได้ เมื่อฉันเห็นไพ่ใบที่สองของฉันฉันสามารถกำจัดได้มากขึ้น 98% และต่อ ๆ ไปจนกระทั่งในที่สุดฉันก็สามารถลงมือหยิบเมล็ดที่เป็นไปได้และรู้ว่ามีโอกาสสูงที่คุณจะได้รับ

ตอนนี้อีกครั้งผมอยากจะเน้นว่าสมมติฐานที่นี่คือถ้าเราเรียกว่าPRNG(6)ล้านครั้งเราจะได้รับในแต่ละจำนวนประมาณหนึ่งในหกของเวลา การกระจายนั่นคือเครื่องแบบ (มากหรือน้อย) และถ้าความสม่ำเสมอของการกระจายนั่นคือสิ่งที่คุณใส่ใจนั่นก็ดี ประเด็นของคำถามคือมีอะไรอีกPRNG(6)บ้างที่การกระจายของสิ่งที่เราใส่ใจ และคำตอบคือใช่ เราใส่ใจเรื่องความคาดเดาไม่ได้เช่นกัน

อีกวิธีหนึ่งในการดูปัญหาคือแม้ว่าการกระจายการโทรหนึ่งล้านครั้งPRNG(6)อาจใช้ได้เนื่องจาก PRNG เลือกจากพฤติกรรมที่เป็นไปได้เพียง 2 32แต่ก็ไม่สามารถสร้างเด็คที่เป็นไปได้ทั้งหมด มันสามารถสร้าง 2 32จาก 2 226ดาดฟ้าที่เป็นไปได้เท่านั้น เศษเสี้ยวเล็ก ๆ ดังนั้นการกระจายตัวของฉากทั้งหมดจึงแย่มาก แต่อีกครั้งการโจมตีขั้นพื้นฐานที่นี่ขึ้นอยู่กับความสามารถของเราในการทำนายพฤติกรรมในอดีตและอนาคตของPRNGตัวอย่างผลลัพธ์ที่ได้

ขอผมใช้นี่เป็นเวลาสามหรือสี่ครั้งเพื่อให้แน่ใจว่าอ่างล้างมือนี้มีการแจกแจงสามแบบตรงนี้ ก่อนการกระจายของกระบวนการที่สร้างเมล็ดพันธุ์แบบสุ่ม 32 บิต ที่สามารถเป็นแบบสุ่มสมบูรณ์ไม่แน่นอนและสม่ำเสมอและการโจมตีจะยังคงทำงาน ประการที่สองการกระจายการโทรหนึ่งล้านPRNG(6)ครั้ง นั่นสามารถเป็นชุดที่สมบูรณ์แบบและการโจมตีจะยังคงทำงาน ประการที่สามการกระจายของสำรับที่เลือกโดยกระบวนการหลอกหลอกที่ฉันได้อธิบายไว้ การกระจายตัวนั้นแย่มาก สามารถเลือกสำรับ IRL ที่เป็นไปได้เพียงเล็กน้อยเท่านั้น การโจมตีขึ้นอยู่กับการคาดการณ์ของพฤติกรรมของ PRNG บนพื้นฐานความรู้บางส่วนของการส่งออกของ

ไซด์: การโจมตีนี้ต้องการให้ผู้โจมตีทราบหรือสามารถเดาได้ว่าอัลกอริทึมที่แน่นอนที่ PRNG ใช้คืออะไร ไม่ว่าจะเป็นจริงหรือไม่เป็นคำถามเปิด อย่างไรก็ตามเมื่อมีการออกแบบระบบรักษาความปลอดภัยที่คุณต้องออกแบบให้เป็นที่เชื่อถือได้ของการโจมตีแม้ว่าโจมตีรู้ขั้นตอนวิธีการทั้งหมดที่อยู่ในโปรแกรม ใส่อีกวิธีหนึ่ง: ส่วนของระบบรักษาความปลอดภัยที่ต้องเก็บเป็นความลับเพื่อให้ระบบมีความปลอดภัยเรียกว่า "กุญแจ" หากระบบของคุณขึ้นอยู่สำหรับการรักษาความปลอดภัยในขั้นตอนวิธีการที่คุณใช้เป็นความลับแล้วที่สำคัญของคุณมีขั้นตอนวิธีการเหล่านั้น นั่นคือตำแหน่งที่อ่อนแออย่างยิ่งที่จะอยู่ใน!

กำลังเดินทางไป.

CPRNGตอนนี้ขอสมมติว่าเรามีกล่องวิเศษที่สามที่มีป้ายกำกับ PRNGมันเป็นรุ่นการเข้ารหัสลับความแข็งแรงของ ใช้เมล็ด 256 บิตแทนที่จะเป็นเมล็ด 32 บิต มันแบ่งปันกับPRNGคุณสมบัติที่เมล็ดเลือกจากหนึ่งใน 2 256พฤติกรรมที่เป็นไปได้ และเช่นเดียวกับเครื่องอื่น ๆ ของเรามันมีคุณสมบัติที่การโทรจำนวนมากเพื่อCPRNG(n)สร้างการกระจายของผลลัพธ์ที่เหมือนกันระหว่าง 1 ถึง n: แต่ละครั้งเกิดขึ้น 1 / n ของเวลา เราสามารถโจมตีมันได้หรือไม่?

โจมตีเดิมของเราเราต้องเก็บ 2 32PRNG(52)แมปจากเมล็ด แต่ 2 256เป็นจำนวนที่มากกว่า มันเป็นไปไม่ได้เลยที่จะรันCPRNG(52)หลาย ๆ ครั้งและเก็บผลลัพธ์

แต่สมมติว่ามีวิธีอื่นที่จะใช้มูลค่าของCPRNG(52)และจากการอนุมานข้อเท็จจริงเกี่ยวกับเมล็ด? เราค่อนข้างจะโง่เง่ามาก่อน เราสามารถตรวจสอบภายในกล่องเวทมนตร์คิดออกว่ามันทำงานอย่างไรและอนุมานข้อเท็จจริงเกี่ยวกับเมล็ดพันธุ์ตามผลผลิต

เลขที่มีรายละเอียดซับซ้อนเกินไปที่จะอธิบาย แต่ CPRNGs ได้รับการออกแบบอย่างชาญฉลาดเพื่อที่จะเป็นไปไม่ได้ที่จะอนุมานใด ๆ ที่ความเป็นจริงมีประโยชน์เกี่ยวกับเมล็ดพันธุ์จากผลผลิตแรกของCPRNG(52)หรือจากใดส่วนหนึ่งของการส่งออกไม่ว่าขนาดใหญ่

ตกลงดังนั้นตอนนี้สมมติว่าเซิร์ฟเวอร์ใช้CPRNGเพื่อสร้างสำรับ มันต้องการเมล็ด 256 บิต มันเลือกเมล็ดพันธุ์นั้นได้อย่างไร? ถ้ามันเลือกค่าใด ๆ ที่ผู้โจมตีสามารถคาดการณ์แล้วก็โจมตีกลายเป็นที่ทำงานได้อีกครั้ง หากเราสามารถระบุได้ว่ามีเมล็ดที่เป็นไปได้2 256เมล็ดนั้นมีเพียง 4 พันล้านรายการเท่านั้นที่มีแนวโน้มที่จะถูกเลือกโดยเซิร์ฟเวอร์ดังนั้นเราจึงกลับมาทำธุรกิจอีกครั้ง เราสามารถหยุดยั้งการโจมตีนี้ได้อีกครั้งโดยให้ความสนใจกับเมล็ดพันธุ์จำนวนเล็กน้อยที่สามารถสร้างได้

เซิร์ฟเวอร์ดังนั้นจึงควรทำผลงานเพื่อให้มั่นใจว่าจำนวน 256 บิตจะกระจายอย่างสม่ำเสมอ - นั่นคือแต่ละเมล็ดเป็นไปได้คือเลือกด้วยความน่าจะเป็นของ 1/2 256 โดยทั่วไปเซิร์ฟเวอร์ควรจะเรียกการสร้างเมล็ดพันธุ์สำหรับTRNG(2^256)-1CPRNG

ถ้าฉันสามารถแฮ็คเซิร์ฟเวอร์และตรวจสอบเพื่อดูว่ามีการเลือกเมล็ดพันธุ์อะไร ในกรณีที่ผู้บุกรุกรู้ว่าที่ผ่านมาที่สมบูรณ์และอนาคตของ CPRNG ผู้เขียนเซิร์ฟเวอร์จำเป็นต้องป้องกันการโจมตีนี้! (แน่นอนถ้าฉันสามารถประสบความสำเร็จในการโจมตีครั้งนี้ได้ฉันก็สามารถโอนเงินไปยังบัญชีธนาคารของฉันได้โดยตรงดังนั้นอาจไม่น่าสนใจประเด็นคือ: เมล็ดต้องเป็นความลับที่ยากต่อการคาดเดาและ ตัวเลข 256 บิตแบบสุ่มอย่างแท้จริงค่อนข้างยากที่จะเดา)

การย้อนกลับไปยังจุดก่อนหน้าของฉันเกี่ยวกับการป้องกันเชิงลึก: เมล็ด 256 บิตเป็นกุญแจสำคัญในระบบรักษาความปลอดภัยนี้ ความคิดของ CPRNG การให้คือระบบที่มีความปลอดภัยตราบใดที่สำคัญคือการรักษาความปลอดภัย ; แม้ว่าทุก ๆ ข้อเท็จจริงเกี่ยวกับอัลกอริทึมเป็นที่รู้จักกันตราบใดที่คุณสามารถเก็บความลับสำคัญบัตรของฝ่ายตรงข้ามไม่สามารถคาดเดาได้

ตกลงดังนั้นเมล็ดควรจะเป็นความลับและกระจายอย่างสม่ำเสมอเพราะถ้าไม่ใช่เราสามารถโจมตีได้ เรามีสมมุติฐานว่าการกระจายตัวของเอาท์พุตCPRNG(n)มีความสม่ำเสมอ สิ่งที่เกี่ยวกับการกระจายไปทั่วชุดของดาดฟ้าที่เป็นไปได้ทั้งหมดหรือไม่

คุณอาจพูดว่า: CPRNG มี 2 256ผลลัพธ์ที่เป็นไปได้ แต่มีเพียง 2 226ดาดฟ้าที่เป็นไปได้ ดังนั้นจึงมีลำดับที่เป็นไปได้มากกว่าเด็คเราจึงไม่เป็นไร เด็ค IRL ที่เป็นไปได้ทั้งหมดตอนนี้ (มีความเป็นไปได้สูง) ที่เป็นไปได้ในระบบนี้ และนั่นเป็นข้อโต้แย้งที่ดียกเว้น ...

2 226เป็นเพียงการประมาณ 52! แบ่งมันออก 2 256/52 ! ไม่สามารถเป็นจำนวนเต็มได้เพราะอย่างใดอย่างหนึ่ง 52! หารด้วย 3 แต่ไม่มีพลังของสองคือ! ตั้งแต่นี้ไม่ได้เป็นจำนวนทั้งหมดตอนนี้เรามีสถานการณ์ที่ชั้นทุกคนมีความเป็นไปได้แต่ชั้นบางมีแนวโน้มมากขึ้นกว่าคนอื่น ๆ

หากยังไม่ชัดเจนให้พิจารณาสถานการณ์ที่มีตัวเลขน้อยกว่า สมมติว่าเรามีไพ่สามใบ A, B และ C สมมติว่าเราใช้ PRNG กับเมล็ด 8 บิตดังนั้นจึงมี 256 เมล็ดที่เป็นไปได้ มีเอาต์พุตที่เป็นไปได้ 256 รายการPRNG(3)ขึ้นอยู่กับเมล็ด ไม่มีทางที่จะมีหนึ่งในสามของพวกเขาเป็น A, หนึ่งในสามของพวกเขาเป็น B และหนึ่งในสามของพวกเขาเป็น C เพราะ 256 ไม่สามารถหารได้อย่างเท่าเทียมกันโดย 3 จะต้องมีอคติเล็ก ๆ ต่อหนึ่งของพวกเขา

ในทำนองเดียวกัน 52 ไม่ได้แบ่งเท่า ๆ กันเป็น 2 256ดังนั้นจึงต้องมีอคติบางอย่างเมื่อเลือกไพ่ใบแรกและมีอคติห่างจากคนอื่น

ในระบบดั้งเดิมของเราที่มีเมล็ด 32 บิตมีอคติมากและดาดฟ้าที่เป็นไปได้ส่วนใหญ่ไม่เคยถูกสร้างขึ้นมา ในระบบนี้ชั้นทั้งหมดสามารถผลิตได้ แต่การกระจายตัวของชั้นก็ยังคงมีข้อบกพร่อง ชั้นบางคนมีมากขึ้นเล็กน้อยจะมีโอกาสมากกว่าคนอื่น ๆ

ตอนนี้คำถามคือ: เรามีการโจมตีตามข้อบกพร่องนี้หรือไม่? และคำตอบคือในทางปฏิบัติอาจจะไม่ได้ CPRNGs ได้รับการออกแบบเพื่อให้ถ้าเมล็ดเป็นแบบสุ่มอย่างแท้จริงแล้วมันเป็นไปไม่ได้คอมพิวเตอร์ที่จะบอกความแตกต่างระหว่างและCPRNGTRNG

ตกลงดังนั้นมาสรุปกัน

ตัวเลขหลอกเทียมและตัวเลขสุ่มแตกต่างกันอย่างไร

พวกเขาแตกต่างกันในระดับของการคาดการณ์ที่พวกเขาแสดง

  • ตัวเลขสุ่มที่แท้จริงไม่สามารถคาดเดาได้
  • ตัวเลขสุ่มหลอกทั้งหมดสามารถคาดการณ์ได้หากเมล็ดสามารถกำหนดหรือเดาได้

ทำไมความแตกต่างจึงสำคัญ

เนื่องจากมีการใช้งานที่การรักษาความปลอดภัยของระบบที่อิงอยู่กับการคาดการณ์

  • หากใช้ TRNG เพื่อเลือกการ์ดแต่ละใบระบบจะไม่สามารถใช้งานได้
  • หากใช้ CPRNG เพื่อเลือกการ์ดแต่ละใบระบบจะปลอดภัยหากทั้งเมล็ดไม่สามารถคาดเดาได้และไม่ทราบ
  • หากใช้ PRNG ธรรมดาที่มีพื้นที่เมล็ดขนาดเล็กระบบจะไม่ปลอดภัยไม่ว่าเมล็ดนั้นจะคาดเดาไม่ได้หรือไม่ทราบก็ตาม พื้นที่เมล็ดเล็กพอที่จะไวต่อการโจมตีที่โหดร้ายแบบที่ฉันอธิบาย

ความแตกต่างมีส่วนเกี่ยวข้องกับการกระจายเอาต์พุตของ PRNG หรือไม่?

ความสม่ำเสมอของการกระจายหรือขาดมันสำหรับการโทรของแต่ละบุคคลที่จะRNG(n)ไม่เกี่ยวข้องกับการโจมตีที่ผมได้อธิบายไว้

ดังที่เราได้เห็นทั้ง a PRNGและCPRNGสร้างการแจกแจงที่ไม่ดีของความน่าจะเป็นในการเลือกเด็คเดี่ยวของเด็คใด ๆ PRNGเป็นอย่างมากที่เลวร้ายยิ่ง แต่ทั้งสองมีปัญหา

อีกหนึ่งคำถาม:

ถ้า TRNG ดีกว่า CPRNG มากซึ่งดีกว่า PRNG มากทำไมใครใช้ CPRNG หรือ PRNG

ด้วยเหตุผลสองประการ

ครั้งแรก: ค่าใช้จ่าย การฝึกซ้อมเป็นที่มีราคาแพง การสร้างตัวเลขสุ่มอย่างแท้จริงนั้นเป็นเรื่องยาก CPRNG ให้ผลลัพธ์ที่ดีสำหรับการโทรจำนวนมากโดยไม่ตั้งใจด้วยการโทรเพียงครั้งเดียวไปยัง TRNG สำหรับเมล็ด แน่นอนว่าคุณต้องเก็บความลับเอาไว้

ประการที่สอง: บางครั้งเราต้องการการคาดการณ์และสิ่งที่เราใส่ใจคือการกระจายที่ดี หากคุณกำลังสร้างข้อมูล "สุ่ม" เป็นโปรแกรมอินพุตสำหรับชุดทดสอบและมันแสดงข้อผิดพลาดมันจะดีถ้าการใช้ชุดทดสอบนั้นสร้างข้อผิดพลาดอีกครั้ง!

ฉันหวังว่าตอนนี้ชัดเจนมากขึ้น

ท้ายที่สุดถ้าคุณชอบสิ่งนี้คุณอาจสนุกกับการอ่านเพิ่มเติมเกี่ยวกับเรื่องของการสุ่มและการเรียงสับเปลี่ยน:


20
ตกลงเด็กชายและเด็กหญิง เพียงพอสำหรับการแสดงความคิดเห็นในตอนนี้ หากคุณต้องการพูดคุยเรื่องนี้ต่อไปลองคว้าห้องแชทด้วยตัวคุณเอง kthnxbye!
Ivo Flipse

1
@Eric แต่เมล็ดไม่ได้ถูกรีเซ็ตก่อนที่จะมีการเด็คใหม่แต่ละครั้งใช่ไหม? ดังนั้นในขณะที่คุณถูกต้องว่ามีเพียงไม่กี่วิถีที่เราสุ่มตัวอย่างจากคุณไม่ทราบว่าในวิถีที่คุณอยู่ในขณะนี้และเส้นทางตัดกัน
AS


การรักษาที่ดี (แต่หนาแน่น) ของปัญหาที่เกี่ยวข้องอยู่ใน Knoc's TAOCP ฉบับที่ 2, ส่วนที่ 3.5“ ลำดับสุ่มคืออะไร?” (หน้า 149) เริ่มต้นด้วยคำจำกัดความที่กระจ่างของ equidistributed ลำดับ Pseudorandom ถูกกล่าวถึงใน 3.5.F (หน้า 170) ดูเพิ่มเติมเกณฑ์ pseudorandomness จากทฤษฎีความซับซ้อนและเยอรมัน BSI
ShreevatsaR

160

อย่างที่ Eric Lippert บอกไว้ไม่ใช่เพียงแค่การแจกจ่ายเท่านั้น มีวิธีอื่นในการวัดแบบแผน

หนึ่งในเครื่องกำเนิดเลขสุ่มก่อนมีลำดับในบิตที่สำคัญน้อยที่สุด - มันสลับ 0 และ 1 ดังนั้น LSB จึงสามารถคาดเดาได้ 100% แต่คุณต้องกังวลมากกว่านั้น แต่ละบิตจะต้องทายไม่ถูก

นี่เป็นวิธีที่ดีในการคิดถึงปัญหา สมมติว่าคุณกำลังสร้างการสุ่ม 64 บิต สำหรับผลลัพธ์แต่ละรายการให้ใช้ 32 บิตแรก (A) และ 32 บิตสุดท้าย (B) และสร้างดัชนีลงในอาร์เรย์ x [A, B] ตอนนี้ทำการทดสอบหนึ่งล้านครั้งและสำหรับผลลัพธ์แต่ละรายการให้เพิ่มอาร์เรย์ที่หมายเลขนั้นเช่น X [A, B] ++;

ตอนนี้วาดไดอะแกรม 2 มิติซึ่งมีจำนวนมากขึ้นความสว่างของพิกเซลที่ตำแหน่งนั้น

หากเป็นการสุ่มอย่างแท้จริงสีควรเป็นสีเทาสม่ำเสมอ แต่คุณอาจได้รูปแบบ ใช้อินสแตนซ์ไดอะแกรมของ "randomness" นี้ในหมายเลขลำดับ TCP ของระบบ Windows NT:

วินโดวส์เอ็นที

หรือแม้แต่อันนี้จาก Windows 98:

Windows 98

และนี่คือการสุ่มของการนำ Cisco router (IOS) ไปใช้ Cisco ISO

แผนภาพเหล่านี้เป็นมารยาทของกระดาษMichał Zalewski ของ ในกรณีนี้หากใครสามารถคาดเดาได้ว่าหมายเลขลำดับ TCP จะเป็นของระบบใครสามารถปลอมตัวเป็นระบบนั้นเมื่อทำการเชื่อมต่อกับระบบอื่น - ซึ่งจะอนุญาตให้หักหลังการเชื่อมต่อการสกัดกั้นการสื่อสาร ฯลฯ และแม้ว่าเราจะ ไม่สามารถคาดเดาหมายเลขถัดไป 100% ของเวลาถ้าเราสามารถทำให้การเชื่อมต่อใหม่ถูกสร้างขึ้นภายใต้การควบคุมของเราเราสามารถเพิ่มโอกาสในการประสบความสำเร็จ และเมื่อคอมพิวเตอร์สามารถสร้างการเชื่อมต่อ 100,000 ครั้งในเวลาไม่กี่วินาทีอัตราต่อรองของการโจมตีที่ประสบความสำเร็จนั้นเกิดจากดาราศาสตร์ไปจนถึงที่เป็นไปได้หรือเป็นไปได้


30
มันยอดเยี่ยมมากมันทำให้น้ำตาของฉัน ควรมีแอพที่สร้างขึ้นสำหรับทุก OS (มือถือ / เดสก์ท็อป / เซิร์ฟเวอร์) และแพลตฟอร์ม (JVM / Javascript / ฯลฯ )
HDave

5
ฟังก์ชั่น rand ของ Windows () ค่อนข้างดี! มันสร้างคลาวด์ที่ไม่มีรูปแบบที่ชัดเจน ดูการใช้งานของฉันเพื่อลอง (และอัลกอริทึมอื่น ๆ ) out: github.com/Zalastax/visualize_random
Zalastax

93

ในขณะที่ตัวเลขสุ่มหลอกที่สร้างขึ้นโดยคอมพิวเตอร์เป็นที่ยอมรับสำหรับกรณีการใช้งานส่วนใหญ่ที่พบโดยผู้ใช้คอมพิวเตอร์มีสถานการณ์ที่ต้องใช้ตัวเลขสุ่มที่คาดเดาไม่ได้อย่างสมบูรณ์

ในแอปพลิเคชันที่มีความปลอดภัยสูงเช่นการเข้ารหัสผู้สร้างหมายเลขปลอม (PRNG) อาจสร้างค่าซึ่งแม้ว่าจะมีการสุ่มปรากฏในความเป็นจริงผู้โจมตีสามารถคาดเดาได้ คนที่พยายามถอดรหัสระบบเข้ารหัสอาจสามารถเดารหัสลับได้หากใช้ PRNG และผู้โจมตีมีข้อมูลเกี่ยวกับสถานะของ PRNG ดังนั้นสำหรับแอปพลิเคชันดังกล่าวตัวสร้างตัวเลขสุ่มซึ่งสร้างค่าที่ไม่สามารถคาดเดาได้อย่างแท้จริงจึงเป็นสิ่งจำเป็น โปรดทราบว่าPRNG บางตัวได้รับการออกแบบให้มีความปลอดภัยในการเข้ารหัสและใช้งานได้สำหรับแอปพลิเคชันที่มีความปลอดภัยสูง

ข้อมูลเพิ่มเติมเกี่ยวกับการโจมตี RNG สามารถพบได้ในบทความวิกิพีเดียนี้


9
การเข้ารหัสลับมี PRNG และใช้กันอย่างแพร่หลาย พวกเขาสามารถจากเมล็ดที่มีขนาดพอประมาณสร้างกระแสสุ่มไม่ จำกัด จำนวน มันเป็นไปไม่ได้ที่จะแยกแยะกระแสดังกล่าวจากการสุ่มตัวเลขที่แท้จริงดังนั้นจึงไม่สามารถรับข้อมูลเพิ่มเติมจากส่วนใด ๆ ของสตรีมดังกล่าวได้และเพื่อประโยชน์ในทางปฏิบัติตัวเลขก็ดีพอ ๆ กับตัวเลขสุ่มจริง
aaaaaaaaaaaa

ฉันคิดว่าวิธีที่ง่ายที่สุดในการอธิบายสิ่งนี้คืออัลกอริทึมตัวสร้างตัวเลขแบบสุ่มต้องถูกตั้งโปรแกรมไว้ นั่นหมายถึงมีชุดคำสั่งที่กำลังปฏิบัติตาม หากมีชุดคำสั่งจะไม่สามารถสุ่มได้
Keltari

6
@Keltari คุณไม่มีองค์ประกอบของเอนโทรปี ... RNGs ส่วนใหญ่ (อย่างน้อยคนที่เข้ารหัสลับ) รวบรวมข้อมูลจากแหล่งภายนอก (เช่นการเคลื่อนไหวของเมาส์) และใช้เป็นส่วนหนึ่งของสภาพเริ่มต้น - ดังนั้นการเปลี่ยนแปลงจากAการBเป็นโปรแกรม แต่ สถานะเริ่มต้นของA(ควร) จะไม่สามารถคาดเดาได้ ลินุกซ์/dev/randomจะคอยประมาณปริมาณเอนโทรปีที่มีอยู่และหยุดให้ตัวเลขถ้ามันต่ำเกินไป
พื้นฐาน

จากความอยากรู้ - ทำไมโคมไฟลาวาจึงถูกพิจารณาว่าเป็น "สุ่มอย่างแท้จริง" ฉันเข้าใจว่ามันแสดงพฤติกรรมที่ไม่สามารถคาดเดาได้ แต่คนที่มีความเข้าใจอย่างเพียงพอเกี่ยวกับการเปลี่ยนแปลงของของไหลและของเหลวเหล่านั้นมีปฏิกิริยาอย่างไรในสภาพแวดล้อมแรงโน้มถ่วงของโลก แน่นอนว่าโคมไฟลาวาไม่แน่นอน แต่สำหรับฉันแล้วมันไม่ได้สุ่มเลย แต่คาดเดาได้สูง
theGreenCabbage

1
@TheGreenCabbage: ฉันสงสัยว่าโคมไฟลาวาวุ่นวาย ด้วยรูปแบบคอมพิวเตอร์ที่ดีเพียงพอและตัวเลขที่มีความแม่นยำเพียงพอคุณสามารถ (ในหลักการ) ทำนายพฤติกรรมในขณะนั้น แต่เนื่องจากระบบไม่เป็นระเบียบโคมลาวาสองดวงที่มีการเปลี่ยนแปลงน้อยที่สุดในสภาวะเริ่มต้นจะแตกต่างอย่างรวดเร็วในพฤติกรรม (และความคิดเห็นนี้ไม่สนใจตัวดึงดูดความวุ่นวาย)
dmm

76

ฉันลองใช้ Python: นี่คือผลลัพธ์ของม้วน 60 ล้าน ความแปรปรวนสูงสุดเท่ากับ 0.15 ไม่ว่าจะเป็นแบบสุ่มที่จะได้รับ?

ที่จริงแล้วมันก็"ดี" ไม่ดี ... คำตอบที่มีอยู่ทั้งหมดมุ่งเน้นไปที่ความสามารถในการคาดเดาได้เนื่องจากค่าเริ่มต้นเล็ก ๆ ฉันต้องการที่จะยกประเด็นอื่น:

    การกระจายของคุณมีค่าเบี่ยงเบนมาตรฐานที่น้อยกว่าการสุ่มม้วน

ทรูสุ่มเพียงแค่ไม่ได้มาค่อนข้างที่ใกล้เคียงกับค่าเฉลี่ย "เกือบตรง 1 มากกว่าวิธีการที่เคยตัวเลขหลาย ๆ คนก็สามารถเลือกได้จาก" ว่าคุณกำลังใช้เป็นตัวบ่งชี้ของการที่มีคุณภาพ

หากคุณดูที่คำถามแลกเปลี่ยนสแต็กเกี่ยวกับการแจกแจงความน่าจะเป็นสำหรับการทอยลูกเต๋าหลายครั้งคุณจะเห็นสูตรสำหรับการเบี่ยงเบนมาตรฐานของการหมุนลูกเต๋า N ลูกเต๋า

 sqrt(N * 35.0 / 12.0).

การใช้สูตรนั้นค่าเบี่ยงเบนมาตรฐานสำหรับ:

  • 1 ล้านม้วนคือ1708
  • 60 ล้านม้วนคือ13229

ถ้าเราดูผลลัพธ์ของคุณ:

  • 1 ล้านม้วน: stddev (10,00066, 999666, 1001523, 999452, 999294, 999999) คือ804
  • 60 ล้านม้วน: stddev (9997653, 9997789, 9996853, 10006533, 10002774, 9998398) คือ3827

คุณไม่สามารถคาดหวังว่าค่าเบี่ยงเบนมาตรฐานของตัวอย่าง จำกัด เพื่อให้ตรงกับสูตร แต่มันควรจะเข้าใกล้ กระนั้นที่ 1 ล้านม้วนคุณน้อยกว่าครึ่งหนึ่งของ stddev ที่ถูกต้องและ 60 ล้านคุณอยู่ในอันดับที่สาม - มันแย่ลงและนั่นไม่ใช่เรื่องบังเอิญ ....

Pseudo-RNGs มีแนวโน้มที่จะเคลื่อนผ่านลำดับของจำนวนที่แตกต่างกันเริ่มต้นด้วยเมล็ดและไม่ได้มาหมายเลขเดิมสำหรับช่วงเวลาที่เฉพาะเจาะจง ตัวอย่างเช่นการใช้งานของrand()ฟังก์ชั่นไลบรารี C เก่ามักมีระยะเวลา 2 ^ 32 และพวกเขาจะเยี่ยมชมทุกหมายเลขระหว่าง 0 และ 2 ^ 32-1 ทุกครั้งก่อนที่จะทำซ้ำเมล็ด ดังนั้นถ้าคุณจำลองลูกเต๋า 2 ^ 32 ลูกเต๋าจะได้ pre-modulus (%) ผลลัพธ์จะรวมแต่ละหมายเลขตั้งแต่ 0 ถึง 2 ^ 32 จำนวนสำหรับแต่ละผลลัพธ์ 1-6 จะเป็น 715827883 หรือ 715827882 (2 ^ 32 ไม่ได้เป็นหลายเท่าของ 6) และค่าเบี่ยงเบนมาตรฐานจึงเบี่ยงเบนไปเหนือ 0 เท่านั้น สูตรข้างต้นค่าเบี่ยงเบนมาตรฐานที่ถูกต้องสำหรับ 2 ^ 32 ม้วนคือ 111924 อย่างไรก็ตามเมื่อจำนวนม้วนของคุณหลอกแบบสุ่มเพิ่มขึ้นคุณจะได้เข้าหา 0 ส่วนเบี่ยงเบนมาตรฐาน คาดว่าปัญหานี้จะเกิดขึ้นอย่างมีนัยสำคัญเมื่อจำนวนม้วนเป็นส่วนสำคัญของช่วงเวลา แต่การปลอมแปลง -RNG บางรายการอาจแสดงปัญหาที่เลวร้ายกว่า - หรือปัญหาแม้จะมีตัวอย่างน้อยกว่า -

ดังนั้นแม้ว่าคุณจะไม่สนใจช่องโหว่การเข้ารหัสในบางแอพพลิเคชั่นคุณอาจสนใจว่ามีการแจกแจงที่ไม่ได้ผลลัพธ์มากจนเกินไป การจำลองบางประเภทค่อนข้างพยายามทำผลที่ตามมาของผลลัพธ์ที่ไม่สม่ำเสมอซึ่งเกิดขึ้นตามธรรมชาติกับตัวอย่างผลลัพธ์แบบสุ่มขนาดใหญ่โดยธรรมชาติ หากคุณพยายามจำลองว่าประชากรจำนวนมากตอบสนองต่อเหตุการณ์บางอย่างปัญหานี้อาจเปลี่ยนแปลงผลลัพธ์ของคุณอย่างรุนแรงซึ่งนำไปสู่ข้อสรุปที่ไม่ถูกต้องอย่างรุนแรง


เพื่อยกตัวอย่างที่เป็นรูปธรรม: สมมติว่านักคณิตศาสตร์บอกโปรแกรมเมอร์เครื่องโป๊กเกอร์ว่าหลังจากที่มีการจำลอง 60 ล้านม้วน - ใช้ในการกะพริบ "ไฟ" เล็ก ๆ น้อย ๆ หลายร้อยรอบหน้าจอหากมีจำนวน 10,013,229 หรือมากกว่าหกซึ่งนักคณิตศาสตร์คาดว่า ห่างจากค่าเฉลี่ย 1 stddev ควรมีการจ่ายเงินเล็กน้อย ตามกฎ 68–95–99.7 (Wikipedia)สิ่งนี้ควรเกิดขึ้นประมาณ16%ของเวลา (ประมาณ 68% อยู่ในค่าเบี่ยงเบนมาตรฐาน / มีเพียงครึ่งเดียวเท่านั้นที่อยู่เหนือ) ด้วยตัวสร้างตัวเลขสุ่มของคุณนี่มาจาก 3.5 ส่วนเบี่ยงเบนมาตรฐานเหนือค่าเฉลี่ย: มีโอกาสต่ำกว่า0.025% - แทบไม่มีลูกค้าที่ได้รับผลประโยชน์นี้ ดูตารางส่วนเบี่ยงเบนที่สูงขึ้นบนหน้าเว็บที่กล่าวถึงโดยเฉพาะ:

| Range    | In range   | Outside range | Approx. freq. for daily event  |
| µ ± 1σ   | 0.68268... | 1 in 3        | Twice a week                   |
| µ ± 3.5σ | 0.99953... | 1 in 2149     | Every six years                |

คุณกำลังเปรียบเทียบแอปเปิ้ลและส้มที่นี่ ส่วนเบี่ยงเบนมาตรฐานทั้งสองไม่มีอะไรเกี่ยวข้องกันเลย
Jbeuh

50

ฉันเพิ่งเขียนตัวสร้างตัวเลขสุ่มนี้เพื่อสร้างลูกเต๋า

def get_generator():
  next = 1
  def generator():
    next += 1
    if next > 6:
      next = 1
    return next
  return generator

คุณใช้มันแบบนี้

>> generator = get_generator()
>> generator()
1
>> generator()
2
>> generator()
3
>> generator()
4
>> generator()
5
>> generator()
6
>> generator()
1

ฯลฯ เป็นต้นคุณมีความสุขที่จะใช้ตัวกำเนิดนี้สำหรับโปรแกรมที่รันเกมลูกเต๋าหรือไม่? โปรดจำไว้ว่าการกระจายของมันคือสิ่งที่คุณคาดหวังจากเครื่องกำเนิด "สุ่มอย่างแท้จริง"!

เครื่องกำเนิดจำนวนสุ่มหลอกทำในสิ่งเดียวกัน - สร้างตัวเลขที่คาดเดาได้ด้วยการแจกแจงที่ถูกต้อง พวกเขาไม่ดีด้วยเหตุผลเดียวกับที่ตัวสร้างตัวเลขสุ่มแบบง่าย ๆ ข้างต้นนั้นไม่ดี - พวกเขาไม่เหมาะสำหรับสถานการณ์ที่คุณต้องการความคาดเดาไม่ได้ของแท้ไม่ใช่แค่การกระจายที่ถูกต้อง


2
"ตัวสร้างตัวเลขสุ่มหลอก ... สร้างตัวเลขที่คาดเดาได้ด้วยการแจกแจงที่ถูกต้อง" - เพียงเพราะ PRNG ไม่รับประกันว่าจะมีการแจกแจงที่สมบูรณ์แบบ เหตุผลที่ระบุไว้ในคำตอบเหล่านี้) ในขณะที่พวกเขาสามารถคาดการณ์ได้รับข้อมูลที่เพียงพอ (algo ใช้เริ่มต้นเมล็ดค่าส่งออก w / e) พวกเขายังคงมีความแปรปรวน
Brian S

3
นอกจากนี้จุดที่ฉันรู้ แต่get_generator = lambda: itertools.cycle(range(1,7)), generator = get_generator(), next(generator) # and so onเป็นเพียงหรูหราเกินไปไม่พูดถึง :)
เจนัส Troelsen

2
@BrianS ที่จริงแล้ว PRNG ที่ล้มเหลวในการทดสอบการกระจายเมื่อเวลาผ่านไปจะสามารถทำนายได้ด้วยคำจำกัดความ ดังนั้นใน N ที่มีขนาดใหญ่ถ้าคุณได้รับแม้แต่นิดหน่อยจาก N / 2 หัวในการโยนเหรียญ N คุณสามารถเริ่มเดิมพันบนหัวและคุณสามารถชนะได้มากกว่าที่คุณแพ้ ในทำนองเดียวกันหากคุณมีการแจกแจงที่สมบูรณ์แบบของหัว v. แต่หัวมาเป็นคู่เสมอคุณจะมีสูตรในการชนะอีกครั้ง การทดสอบการกระจายเป็นวิธีที่คุณรู้ว่า PRNG นั้นดีอย่างไร
Jon Kiparsky

1
คุณลืมnonlocal next:-)
Kos

5
ตัวอย่างที่ดียิ่งขึ้น: Pi เชื่อว่าเป็นเรื่องปกติซึ่งหมายความว่าลำดับของตัวเลขใด ๆ ของความยาวที่กำหนดในฐานใด ๆ ไม่ปรากฏบ่อยกว่าลำดับอื่น ๆ ของความยาวนั้นในฐานนั้น อัลกอริทึมซึ่งเมื่อถามถึงบิตสุ่มnจะใช้เวลาบิตnถัดไปของ pi และส่งกลับพวกเขา ("เมล็ดพันธุ์" เป็นบิตที่คุณเริ่มต้น) ควรในระยะยาวจะสร้างการกระจายที่สมบูรณ์แบบ แต่คุณยังคงไม่ต้องการมันสำหรับเครื่องกำเนิดไฟฟ้าของคุณ - คนที่รู้ว่าบิตสุดท้ายที่คุณสร้างขึ้นสามารถหาได้ในครั้งแรกที่มีการเรียงลำดับเกิดขึ้นสมมติว่าเมล็ดของคุณอยู่ที่นั่นและน่าจะถูกต้อง
cpast

26

การสร้างตัวเลขสุ่มที่คอมพิวเตอร์ของคุณสามารถทำได้นั้นเหมาะสำหรับความต้องการส่วนใหญ่และคุณไม่น่าจะเจอเวลาที่คุณต้องการตัวเลขสุ่มอย่างแท้จริง

การสร้างหมายเลขสุ่มที่แท้จริงนั้นมีจุดประสงค์ ในเรื่องความปลอดภัยของคอมพิวเตอร์การพนันการสุ่มตัวอย่างเชิงสถิติขนาดใหญ่ ฯลฯ

หากคุณมีความสนใจในการใช้งานของตัวเลขสุ่มตรวจสอบบทความวิกิพีเดีย


12
ปัญหาใหญ่คือเมื่อคุณต้องการตัวเลขสุ่มที่ผู้โจมตีไม่สามารถทำนายได้ด้วยเหตุผลด้านความปลอดภัย
David Schwartz

16
คุณแน่ใจว่าเป็นนรกที่จะเจอเวลาที่คุณต้องการตัวเลขสุ่มอย่างแท้จริง ก็เพียงพอแล้วที่จะเปิดหน้าเว็บที่เริ่มต้นด้วยhttps://...
Jan Hudec

3
@JanHudec: ดีในการใช้ชีวิตประจำวันคุณจะต้องสุ่มตัวเลขที่เชื่อถือได้ของช่วงเวลาที่คุณเปิดโปรแกรมใด ๆ ให้ดีก่อนที่คุณกำลังพิมพ์ลงในแถบที่อยู่: ดูอยู่ randomization นั่นเป็นเหตุผลว่าทำไมเรื่องแบบนี้ถึงเกิดขึ้น
Reid

5
@JanHudec ฉันกำลังพูดเฉพาะในแง่ที่คุณจะต้องใช้เครื่องกำเนิดตัวเลขแบบสุ่มออนไลน์ ตัวเลขสุ่มจริงใช้บ่อย แต่มีคนน้อยมากที่ต้องการสร้างมัน
Alex McKenzie

2
เครื่องสล็อตใช้ PRNG ไม่ใช่ TRNG เครื่องกำเนิดไฟฟ้าจะทำงานตลอดเวลาและจะมีการเลือกตัวเลขในเวลาที่แน่นอนว่าจะกดปุ่มหมุน ผลรวมของ PRNG และเวลากดปุ่มสุ่มอย่างแท้จริงจะเท่ากับ TRNG
Roger Dahl

26

ตัวเลขสุ่มที่สร้างโดยฟังก์ชั่นทั่วไปในภาษาการเขียนโปรแกรมส่วนใหญ่ไม่ใช่ตัวเลขสุ่มล้วน พวกเขาเป็นตัวเลขสุ่มหลอก เนื่องจากตัวเลขเหล่านี้ไม่ใช่ตัวเลขสุ่มอย่างเดียวพวกเขาจึงสามารถคาดเดาได้ว่ามีข้อมูลเพียงพอเกี่ยวกับตัวเลขที่สร้างขึ้นก่อนหน้านี้ ดังนั้นนี้จะเป็นภัยพิบัติเพื่อความปลอดภัยในการเข้ารหัส

ตัวอย่างเช่นฟังก์ชั่นตัวสร้างตัวเลขสุ่มต่อไปนี้ที่ใช้ในglibcนั้นไม่ได้สร้างหมายเลขสุ่มอย่างแท้จริง หมายเลขสุ่มหลอกที่สร้างโดยสิ่งนี้สามารถเดาได้ มันเป็นความผิดพลาดสำหรับปัญหาด้านความปลอดภัย มีประวัติของการกลายเป็นหายนะ สิ่งนี้ไม่ควรใช้ในการเข้ารหัส

glibc random():
    r[i] ← ( r[i-3] + r[i-31] )  % (2^32)
    output  r[i] >> 1

ตัวสร้างตัวเลขสุ่มหลอกชนิดนี้ไม่ควรใช้ในสถานที่ปลอดภัยด้านความปลอดภัยแม้ว่าจะมีนัยสำคัญทางสถิติ

หนึ่งของการโจมตีที่มีชื่อเสียงบนปุ่มสุ่มหลอกคือการโจมตีใน802.11b WEP WEP มีคีย์ระยะยาว 104 บิตเชื่อมต่อกับ 24 บิต IV (ตัวนับ) เพื่อสร้างคีย์ 128 บิตซึ่งจะนำไปใช้กับอัลกอริทึม RC4เพื่อสร้างคีย์สุ่มหลอก

( RC4( IV + Key ) ) XOR (message)

กุญแจมีความสัมพันธ์อย่างใกล้ชิดกับอีกคนหนึ่ง ที่นี่เพียง IV เพิ่มขึ้น 1 ในแต่ละขั้นตอนและอื่น ๆ ทั้งหมดยังคงเหมือนเดิม เนื่องจากนี่ไม่ใช่การสุ่มอย่างแท้จริงมันจึงเป็นหายนะและพังทลายได้ง่าย กุญแจสามารถกู้คืนได้โดยการวิเคราะห์เฟรมประมาณ 40000 ซึ่งเป็นเวลาไม่กี่นาที หาก WEP ใช้การสุ่ม 24 บิต IV แบบสุ่มทั้งหมดอาจปลอดภัยจนกว่าเฟรมประมาณ 2 ^ 24 (เกือบ 16.8 ล้าน)

ดังนั้นหนึ่งควรไปกับเครื่องกำเนิดตัวเลขบริสุทธิ์ในประเด็นความปลอดภัยที่เป็นไปได้


3
ฉันจะตำหนิสิ่ง WEP ในโปรโตคอลที่ออกแบบมาไม่ดีโดยใช้ตัวเลขที่อ่อนแอ ด้วยยันต์กระแสอันทันสมัยคุณสามารถใช้ตัวนับเป็น IV
CodesInChaos

2
ปัญหาหลักของ WEP คือการทำซ้ำกุญแจในเฟรม 2 ^ 24 (เกือบ 16 ล้าน) มันยิ่งแย่ลงไปกว่านี้ด้วยกุญแจที่เกี่ยวข้องซึ่งทำให้สามารถถอดรหัสรหัสได้ประมาณ 40000 เฟรม จุดหลักที่นี่คือกุญแจไม่ได้สุ่ม มันมีความสัมพันธ์กันอย่างใกล้ชิดดังนั้นมันจึงแตกง่าย
Prabhu

1
หลอกแบบแผนคือไม่ดีในการเข้ารหัสเฉพาะเมื่อมีการสร้างคีย์การเข้ารหัสลับ มันสมบูรณ์แบบดีกว่านั้น แท้จริงแล้ว RC4 นั้นเป็นเครื่องกำเนิดตัวเลขแบบหลอกเทียมที่มีการขยายตัวของคีย์ XOR ที่ 128 บิตลงบนข้อความธรรมดา
แมตต์

12

ความแตกต่างคือตัวเลขที่สร้างขึ้นแบบสุ่มสามารถคาดเดาได้ (ทำซ้ำ) หลังจากระยะเวลาหนึ่งซึ่งไม่มีการสุ่มตัวเลขจริง ความยาวที่ใช้ในการทำซ้ำขึ้นอยู่กับความยาวของเมล็ดซึ่งใช้สำหรับการสร้าง

นี่เป็นวิดีโอที่ดีเกี่ยวกับหัวข้อนั้น: http://www.youtube.com/watch?v=itaMNuWLzJo


Predictability! = การทำซ้ำ Mersenne Twister เป็นตัวอย่างที่ดีของสิ่งนั้น ในการติดตั้งส่วนใหญ่หลังจาก 624 Int32 คุณสามารถทำนายหมายเลขถัดไปทั้งหมด แต่ลำดับ Mersenne Twister นั้นยาวกว่านั้นมาก (2 ^ 19937 - 1)
HoLyVieR

ฉันไม่เข้าใจว่าทำไมคำตอบนี้ไม่ได้ทำให้เกิดสแต็คเพราะฉันคิดว่านี่เป็นคำตอบที่ถูกต้องและรัดกุมสำหรับคำถามอย่างน้อยบางส่วน ตัวเลขสุ่มหลอกสามารถทำนายได้อย่างง่ายดายหลังจากการจับรางวัลจำนวนการจับคู่ที่แตกต่างกันกับอัลกอริธึมหลอกหลอก "คุณภาพ" การเลือกอัลกอริทึม "ดี" กำลังมองหาที่ด้านต่างๆ: 1. ทุกค่าถูกวาดด้วยความถี่เท่ากัน (การกระจาย) 2. ใช้เวลา "นาน" ในการรีสตาร์ทลำดับที่จุดเริ่มต้นและเริ่มวาดตัวเลขเดียวกันใน คำสั่งเดียวกัน
นาที

"ตัวเลขสุ่มจริงไม่ใช่ [คาดเดาได้]" สำหรับวันนี้มันเป็นเรื่องจริง ทีนี้ถ้าเราเชื่อในทฤษฎีบิ๊กแบงและเรามีพลังมากมายในการคำนวณสถานะของจักรวาลในเวลาใดก็ได้หลังจาก BB ตามฟิสิกส์แล้ว ... เราสามารถทำนายอนาคตรวมถึงข้อเท็จจริงที่ว่า ฉันกำลังเขียนความคิดเห็นที่แน่นอนมากนี้ ขวา?
นาที

นั่นเป็นความจริงตามสมมุติฐานอย่างไรก็ตามเมื่อพิจารณาถึงระดับของเอนโทรปีที่เกี่ยวข้องกับการกระทำจริงของร่างกายจริง ๆ พลังการคำนวณที่จำเป็นจะยิ่งใหญ่อย่างน่าขัน คิดว่าทวีปครอบคลุมในคอมพิวเตอร์ นอกจากนี้เนื่องจากการพึ่งพารัฐก่อนหน้านี้สถานะของร่างกายทุกคนในจักรวาลในทุกจุดในเวลาจะต้องถูกเก็บไว้ซึ่งตามคำนิยามจะต้องมีพื้นที่ว่างมากกว่าที่มีอยู่ในจักรวาลที่เต็มไปด้วยอุปกรณ์หน่วยความจำ
TheEnvironmentalist

@TheEnvironmentalist - อ้า! "ทวีปที่กล่าวถึงในคอมพิวเตอร์" ... ไม่ใช่หรือสิ่งที่ "คู่มือโบกรถของกาแล็กซี่" เกี่ยวกับ? ;-)
ysap

10

สมมติว่าทุกคนก่อนที่มันจะถูกสร้างขึ้นเดาตัวเลขสุ่มหลอก

สำหรับแอปพลิเคชั่นเล็ก ๆ น้อย ๆ การสุ่มหลอกก็ดีเช่นเดียวกับตัวอย่างของคุณคุณจะได้รับเปอร์เซ็นต์ที่ถูกต้อง (ประมาณ 1 ใน 6 ของชุดผลลัพธ์ทั้งหมด) โดยมีการเปลี่ยนแปลงเล็กน้อย (ซึ่งคุณจะเห็นว่าคุณจะกลิ้งลูกเต๋า 600k ครั้ง);

อย่างไรก็ตามเมื่อพูดถึงเรื่องความปลอดภัยของคอมพิวเตอร์ จำเป็นต้องมีการสุ่มตัวอย่างที่แท้จริง

ตัวอย่างเช่นอัลกอริทึม RSA เริ่มต้นด้วยคอมพิวเตอร์ที่เลือกตัวเลขสุ่มสองตัว (P และ Q) จากนั้นทำหลายขั้นตอนกับตัวเลขเหล่านั้นเพื่อสร้างหมายเลขพิเศษที่รู้จักกันในชื่อกุญแจสาธารณะและกุญแจส่วนตัวของคุณ (ส่วนสำคัญของคีย์ส่วนตัวคือเป็นส่วนตัวและไม่มีใครรู้เลย!)

หากผู้โจมตีสามารถรู้ว่า 'สุ่ม' สองหมายเลขใดที่คอมพิวเตอร์ของคุณกำลังจะเลือกพวกเขาสามารถทำตามขั้นตอนเดียวกันเพื่อคำนวณคีย์ส่วนตัวของคุณ (หมายเลขที่คนอื่นไม่ควรรู้!)

ด้วยรหัสส่วนตัวของคุณผู้โจมตีสามารถทำสิ่งต่าง ๆ เช่นก) พูดคุยกับธนาคารของคุณว่าเป็นคุณข) ฟังการรับส่งข้อมูลทางอินเทอร์เน็ตที่ปลอดภัยและสามารถถอดรหัสได้ c) การปลอมตัวระหว่างคุณกับฝ่ายอื่น ๆ บนอินเทอร์เน็ต

นั่นคือสิ่งที่จำเป็นต้องมีการสุ่มตัวอย่างที่แท้จริง (เช่นไม่สามารถเดา / คำนวณ)


10

ตัวเลขสุ่มตัวแรกที่ฉันเคยใช้มีคุณสมบัติที่ยอดเยี่ยมของตัวเลขสุ่มสองตัวติดต่อกันหมายเลขที่สองนั้นใหญ่กว่าด้วยความน่าจะเป็นที่ 0.6 ไม่ใช่ 0.5 และอันที่สามใหญ่กว่าวินาทีด้วยความน่าจะเป็น 0.6 และอื่น ๆ คุณสามารถจินตนาการได้ว่าวิธีเล่นความเสียหายด้วยการจำลอง

บางคนไม่เชื่อว่านี่เป็นไปได้แม้จะมีการแจกแจงตัวเลขแบบสุ่ม แต่ก็เห็นได้ชัดว่าถ้าคุณดูลำดับ (1, 3, 5, 2, 4, 1, 3, 5, 2, 4, ... ) โดยที่สองของตัวเลขสองตัวมีค่ามากกว่าความน่าจะเป็น 0.6

ในทางกลับกันสำหรับการจำลองเป็นสิ่งสำคัญที่จะสามารถทำซ้ำตัวเลขสุ่ม สมมติว่าคุณทำการจำลองการรับส่งข้อมูลและต้องการทราบว่าการดำเนินการบางอย่างที่คุณอาจทำได้สามารถปรับปรุงปริมาณการใช้งานได้อย่างไร ในกรณีนี้คุณต้องการที่จะสร้างข้อมูลการจราจรเดิมซ้ำอีกครั้ง (เช่นผู้ที่พยายามเข้าเมือง) ด้วยการกระทำที่แตกต่างกันซึ่งคุณพยายามปรับปรุงการจราจร


8

คำตอบสั้น ๆ ก็คือคนมักจะต้องการ "การสุ่มอย่างแท้จริง" ด้วยเหตุผลที่ไม่ดีนั่นคือพวกเขาไม่มีความเข้าใจในการเข้ารหัส

การเข้ารหัสดั้งเดิมเช่นstream ciphersและCSPRNGsถูกใช้เพื่อสร้างกระแสข้อมูลจำนวนมากของบิตที่ไม่สามารถคาดเดาได้เมื่อพวกมันได้รับการป้อนบิตที่ไม่สามารถคาดเดาได้สองสามตัว

ตอนนี้ผู้อ่านที่ระวังจะรู้ว่ามีปัญหาเรื่อง bootstrapping ที่นี่: เราต้องรวบรวมเอนโทรปีสองสามตัวเพื่อเริ่มต้นมันทั้งหมด จากนั้นสามารถป้อนเข้าสู่CSPRNGซึ่งจะให้บิตที่คาดเดาไม่ได้ทั้งหมดที่เราต้องการอย่างมีความสุข ดังนั้นRNG ฮาร์ดแวร์จะต้องเมล็ด CSPRNG นี่เป็นกรณีเดียวที่จำเป็นต้องใช้เอนโทรปีในความจริง

(ฉันคิดว่าสิ่งนี้ควรถูกโพสต์ในการรักษาความปลอดภัยหรือการเข้ารหัส)

แก้ไข: ในท้ายที่สุดหนึ่งจะต้องเลือกตัวสร้างตัวเลขสุ่มซึ่งดีพอสำหรับงานที่คาดการณ์ไว้และเท่าที่การสร้างตัวเลขสุ่มเกี่ยวข้องกับฮาร์ดแวร์ไม่จำเป็นต้องถือเอาว่าดี เช่นเดียวกับ PRNG ที่ไม่ดีแหล่งที่มาแบบสุ่มของฮาร์ดแวร์มักจะมีอคติ

แก้ไข: บางคนคิดว่ารูปแบบการคุกคามที่ผู้โจมตีสามารถอ่านสถานะภายในของ CSPRNG และจากนั้นไปที่บทสรุปว่า CSPRNG ไม่ใช่ทางออกที่ปลอดภัย นี่คือตัวอย่างของการสร้างแบบจำลองเธรดที่ไม่ดี หากผู้โจมตีเป็นเจ้าของระบบของคุณเกมจะจบลงและเรียบง่าย ไม่ได้สร้างความแตกต่างใด ๆ ไม่ว่าคุณจะใช้ TRNG หรือ CSPRNG ณ จุดนี้

แก้ไข: ดังนั้นเพื่อรวมทั้งหมดนี้ ... เอนโทรปีจำเป็นต้องมีการเพาะ CSPRNG เมื่อดำเนินการเสร็จ CSPRNG จะจัดหาบิตที่คาดเดาไม่ได้ทั้งหมดที่เราต้องการสำหรับแอปพลิเคชันความปลอดภัยเร็วกว่าที่เราสามารถรวบรวมเอนโทรปีได้มาก หากไม่จำเป็นต้องคาดเดาไม่ได้เช่นสำหรับการจำลอง Mersenne Twister จะให้ตัวเลขที่มีคุณสมบัติทางสถิติที่ดีในอัตราที่สูงขึ้นมาก

แก้ไข: ทุกคนยินดีที่จะเข้าใจปัญหาการสร้างหมายเลขสุ่มที่ปลอดภัยควรอ่าน: http://www.cigital.com/whitepapers/dl/The_Importance_of_Reliable_Randomness.pdf


2
มันไม่จำเป็นต้องเป็นคำถามเพื่อความปลอดภัย ฉันคิดว่ามีเหตุผลที่จะใช้ตัวเลขสุ่มที่ไม่เกี่ยวข้องกับความปลอดภัย ถ้าฉันกำลังทำการวิจัยทางวิทยาศาสตร์ที่ขึ้นอยู่กับตัวเลขสุ่มและด้วยเหตุผลใดก็ตามที่สำคัญว่าตัวเลขนั้นสุ่มที่สุดฉันจะใช้ประโยชน์จากฮาร์ดแวร์ RNG อย่างแน่นอนดังนั้นฉันจึงมั่นใจได้ว่าคุณสมบัติที่สังเกตเห็นจะไม่ครบกำหนด ถึงนิสัยใจคอของ RNG
Kef Schecter

3
@KefSchecter มันเป็นฮาร์ดแวร์ PRNGs ของพวกเขาได้ยินโดยทั่วไปมีลำเอียงและ / หรือผลผลิตที่มีความสัมพันธ์ พวกเขาต้องการขั้นตอนการโพสต์เพื่อเปลี่ยนเป็นเอาท์พุทอิสระสม่ำเสมอ ไม่มีเหตุผลที่เชื่อได้ว่าขั้นตอนการโพสต์นี้มีความน่าเชื่อถือมากกว่าการเข้ารหัสสตรีมที่ทันสมัย แน่นอนฉันจะเชื่อกระแสข้อมูลตัวเลขเพิ่มเติม ในฐานะโบนัสพิเศษมันสามารถทำซ้ำได้ซึ่งมีคุณค่าทางวิทยาศาสตร์
CodesInChaos

ตกลงยุติธรรมพอ แต่แอปพลิเคชันการเข้ารหัสจะไม่เหมือนกันหรือไม่ แม้แต่คำตอบที่นี่ก็บอกว่าคุณต้องการฮาร์ดแวร์ RNG เพื่อเพาะเมล็ด CSPRNG
Kef Schecter

2
@KefSchecter ใช่แล้วแอปพลิเคชัน crypto ต้องการตัวเลขสุ่มจริง ๆ เพื่อเริ่มต้น CSPRNG แต่สำหรับทุกอย่างเราสามารถใช้ CSPRNG นั้นได้
CodesInChaos

@KefSchecter: แอพพลิเคชั่นการเข้ารหัสต้องการให้โลกไม่สามารถทำซ้ำกระแสข้อมูลได้ ในทางวิทยาศาสตร์การใช้ความสามารถในการแสดงให้เห็นว่าตัวเลข "สุ่ม" ที่ใช้ไม่ได้ถูกเลือกเพื่อแสดงการวิเคราะห์ในแง่ดีนั้นมีประโยชน์ ตัวอย่างเช่นหากมีการประกาศหลังจากประกาศวิธีการหนึ่งว่าจะสร้างข้อมูลในรูปแบบที่แน่นอนโดยใช้หมายเลขล็อตเตอรี่ของรัฐในวันถัดไปผู้อ่านสามารถมั่นใจได้ว่าจะไม่ได้รับผลการค้นหาแม้ว่าการวาดในวันธรรมดา บิตของเอนโทรปี
supercat

7

PRNG ไม่เหมาะสำหรับการใช้งานทุกประเภท ตัวอย่างเช่น Java.util.SecureRandom ใช้แฮช SHA1 ซึ่งมีขนาดเอาต์พุต 160 บิต นั่นหมายความว่ามีสตรีมสุ่มตัวเลขที่เป็นไปได้2 160สตรีที่มาจากมัน เรียบง่ายเหมือนที่ คุณไม่สามารถรับค่าภายในมากกว่า 2 160ค่าของสถานะภายใน ดังนั้นคุณจะไม่สามารถรับ หมายเลขสุ่มที่เป็นเอกลักษณ์มากกว่า 2 160 รายการจากเมล็ดเดี่ยวไม่ว่าเมล็ดของคุณจะมาจากที่ใด Windows CryptGenRandom เชื่อว่าใช้สถานะแบบ 40 ไบต์มีตัวเลขสุ่มได้ถึง320 320ตัว

หลายวิธีที่จะสับเปลี่ยนดาดฟ้า 52 ใบมาตรฐานคือ 52 !, ซึ่งมีประมาณ 2 226 ดังนั้นโดยไม่คำนึงถึงการเพาะคุณไม่สามารถใช้ Java.util.SecureRandom เพื่อสับไพ่ได้ มีประมาณ 2 66สับที่เป็นไปได้ที่มันไม่สามารถผลิตได้ แน่นอนเราไม่รู้ว่าพวกเขาเป็นใคร ...

ดังนั้นถ้าฉันมีแหล่งที่มาของการพูดแบบสุ่ม 256 บิต (เช่นจากการ์ด Quantis RNG) ฉันสามารถหว่าน PRNG เช่น CryptGenRandom () ด้วยเมล็ดนั้นแล้วใช้ PRNG เพื่อสับชั้นของ บัตร ถ้าฉันสุ่มด้วยการสุ่มแบบสุ่มแต่ละครั้งจะดี: สุ่มไม่แน่นอนและมีสถิติ ถ้าฉันทำสิ่งเดียวกันกับ Java.util.SecureRandom จะมี shuffles ที่ไม่สามารถผลิตได้เพราะมันไม่สามารถ seed ด้วยเอนโทรปี 256 บิตและสถานะภายในของมันไม่สามารถเป็นตัวแทนของ shuffles ที่เป็นไปได้ทั้งหมด

โปรดทราบว่าผลลัพธ์ java.util.SecureRandom จะเป็นทั้งการคาดเดาไม่ได้และการสุ่มทางสถิติ ไม่มีการทดสอบทางสถิติที่จะระบุปัญหา! แต่ผลลัพธ์ของ RNG นั้นไม่ใหญ่พอที่จะครอบคลุมโดเมนทั้งหมดของผลลัพธ์ที่เป็นไปได้ทั้งหมดที่จำเป็นในการจำลองสำรับไพ่

และจำไว้ว่าถ้าคุณเพิ่มนักเลงเข้าไปก็คือ 54! ที่คุณต้องครอบคลุมซึ่งต้องมีความเป็นไปได้ประมาณ 2 238


2
ทำไมคุณถึงสนใจว่าสับบางอย่างไม่สามารถเกิดขึ้นได้? ข้อ จำกัด นั้นไม่มีผลที่สังเกตได้
CodesInChaos

2
ฉันกำลังเรียงลำดับ gobsmacked คำถาม สำหรับ บริษัท เกมที่มีการควบคุมอย่างเข้มงวดอคติทางคณิตศาสตร์จะพิสูจน์ได้ว่าโอกาสในการชนะเกมการ์ดนั้นแตกต่างจากคอมพิวเตอร์มากกว่าที่จะเป็นการ์ดกระดาษ ไม่สำคัญว่าโอกาสดีกว่าหรือแย่กว่านั้น พวกมันต่างกัน คอมพิวเตอร์ไม่ได้มีคุณธรรมเทียบเท่ากับเด็คแท้ ยิ่งกว่านั้นเราไม่สามารถอธิบายลักษณะที่แตกต่างได้ บริษัท เกมที่ต้องเผชิญกับค่าปรับที่เข้มงวดจะต้องใส่ใจเป็นอย่างมาก
Paco Hope

1
แต่มันตรวจจับได้ ฉันตรวจพบโดยใช้กระบวนการที่ทราบ: การตรวจทานซอร์สโค้ดและความรู้เกี่ยวกับโดเมนปัญหา นั่นคือสิ่งที่น่าทึ่ง ฉันไม่สามารถใช้การวิเคราะห์ทางสถิติอัตโนมัติ มันสามารถตรวจพบได้เหมือนคนที่ใช้ java.util.Random หรือ Mersenne Twister การวิเคราะห์เชิงสถิติไม่ใช่กลไกการตรวจสอบที่ถูกต้องเพียงอย่างเดียวสำหรับ RNG / ปัญหาโดเมนไม่ตรงกัน ความล้มเหลวที่ผ่านการตรวจจับนั้นไม่ประสบความสำเร็จตามคำจำกัดความ
Paco Hope

1
ฉันไม่เคยเห็นด้วยกับข้อความนั้น สิ่งที่ฉันพูดคือการวิเคราะห์ทางสถิตินั้นไม่สามารถพิสูจน์ได้ว่า RNG / PRNG นั้นถูกต้อง นี่คือตัวอย่างของการลบที่ผิดพลาด มันควรจะไม่ถูกต้อง แต่การทดสอบผลลัพธ์ทางสถิติจะผ่านมัน ถ้าฉันใช้ SHA1 (1), SHA1 (2), SHA1 (3) ... SHA1 (n) เป็น "RNG" ของฉันที่จะผ่านการทดสอบทางสถิติด้วย มันก็ผิด คำจำกัดความของการแก้ไขที่ถูกต้องขยายเกินคำจำกัดความของ "ผ่านการทดสอบทางสถิติ" จำเป็นต้องผ่านการทดสอบทางสถิติ แต่ไม่เพียงพอ
Paco Hope

4
@CodesInChaos: อาร์กิวเมนต์ "เราไม่ทราบว่ามีการโจมตีที่สามารถใช้ประโยชน์จากความจริงที่ว่าส่วนใหญ่ที่เป็นไปได้ - IRL - shuffles จะไม่ถูกผลิต" ไม่ได้หมายความว่าการโจมตีดังกล่าวเป็นไปไม่ได้เพียงแค่ว่าเราไม่ ไม่รู้ว่ามันคืออะไรหรือจะป้องกันอย่างไร ทัศนคติที่ถูกต้องในกรณีนั้นคือการกำจัดความเป็นไปได้ของการโจมตีโดยกำจัดเงื่อนไข: สร้าง RNG ที่มีคุณภาพเพียงพอที่จริงสามารถสร้างสำรับที่เป็นไปได้ทั้งหมด
Eric Lippert

6

หมายเลข Pseudorandom ถูกสร้างขึ้นโดยใช้ฟังก์ชั่นทางคณิตศาสตร์และค่าเริ่มต้น (เรียกว่าเมล็ด ) ในขณะที่ตัวเลขสุ่มไม่ได้ ความสามารถในการคาดการณ์ของพวกเขาทำให้พวกเขามีประโยชน์อย่างเหลือเชื่อสำหรับการเล่นเกมเนื่องจากคุณต้องการบันทึกเมล็ดพันธุ์และข้อมูลผู้เล่นเท่านั้น AI จะตอบสนองในแบบ "สุ่ม" ที่แน่นอนทุกครั้ง


6

ความแตกต่างระหว่างตัวเลขสุ่ม "จริง" และ "หลอก" คือความสามารถในการคาดการณ์ คำตอบนี้มีให้แล้ว

อย่างไรก็ตามความสามารถในการคาดการณ์ไม่จำเป็นต้องเป็นสิ่งที่แย่เหมือนตัวอย่างส่วนใหญ่ที่แสดง นี่คือตัวอย่างการใช้งานจริงของหนึ่งในกรณีที่หายากซึ่งการคาดการณ์ได้ดี: ระบบกำหนดตำแหน่งทั่วโลก

ดาวเทียมแต่ละดวงใช้รหัส PRN ที่แตกต่างกัน ( รหัสทองคำ ) ที่เหมาะสมสำหรับความสัมพันธ์อัตโนมัติหรือความสัมพันธ์ข้ามซึ่งเป็นสิ่งจำเป็นสำหรับการวัดเวลาการแพร่กระจายสัญญาณ สำหรับรหัสทองเหล่านี้ความสัมพันธ์ระหว่างกันนั้นอ่อนแอเป็นพิเศษทำให้สามารถระบุตัวตนของดาวเทียมได้อย่างชัดเจน แต่อนุญาตให้คำนวณระยะทางโดยความสัมพันธ์ระหว่างลำดับที่ปล่อยออกมาและตัวรับ


2

สำหรับการตรวจสอบแบบสุ่มอย่างรวดเร็วคุณจะได้คะแนนด้วยการสุ่มพิกัดใน [0; 1) จากนั้นใส่มันลงในคิวบ์คิว - มิติ จากนั้นคุณทำโพรซีเดอร์เพื่อแบ่งลูกบาศก์นี้เป็น subcubes - แต่ละวอลุ่มของ subcube (หรือ subsphere) ต้องถูกวัดอย่างถูกต้องโดยโพรซีเดอร์นี้พร้อมกับความผันผวนตามทฤษฎีบทที่รู้จักกันดี

คุณภาพของการสุ่มเป็นสิ่งสำคัญที่คุณพบ ...

  1. วัตถุประสงค์ด้านความปลอดภัย เมื่อคุณสร้างตัวเลขเพื่อใช้เป็นพารามิเตอร์สำหรับการสร้างคีย์ของคุณและสามารถคาดเดาได้ดี - ศัตรูจะพบว่ามันมีความน่าจะเป็น 100% และทำให้ฟิลด์สำหรับการค้นหามีขนาดเล็กลงมาก

  2. วัตถุประสงค์ทางวิทยาศาสตร์ ในทางวิทยาศาสตร์คุณจะต้องไม่เพียง แต่มีค่าเฉลี่ยอยู่ในสภาพดี แต่ยังต้องกำจัดความสัมพันธ์ระหว่างตัวเลขสุ่มต่างๆด้วย ดังนั้นหากคุณใช้ (a_i - a) (a_ {i + 1} -a) และค้นหาการแจกแจงมันต้องสอดคล้องกับสถิติ

ความสัมพันธ์ของคู่นั้นเรียกว่า "การสุ่มแบบอ่อนแอ" หากคุณต้องการการสุ่มที่แท้จริงคุณต้องมีความสัมพันธ์ลำดับสูงกับความแปรปรวนมากกว่า 2

ทุกวันนี้มีเพียงผู้สร้างกลศาสตร์ควอนตัมเท่านั้นที่ให้การสุ่มอย่างแท้จริง


1

เหตุใดการสุ่มตัวอย่างที่แท้จริงจึงสำคัญ

โดยทั่วไปมีสองสาเหตุหลักที่ทำให้การสุ่มตัวอย่างเป็นสิ่งจำเป็น:

  1. หากคุณกำลังใช้ RNG สำหรับการเข้ารหัส (รวมถึงสิ่งต่าง ๆ เช่นการพนันด้วยเงินจริงและการจับสลาก) PRNG จะทำให้คุณรู้สึกอ่อนแอกว่าการวิเคราะห์ทางคณิตศาสตร์ (ซึ่งถือว่า TRNG) จะทำให้คุณเชื่อ PRNG จะไม่ถูกสุ่ม แต่มีรูปแบบ - ฝ่ายตรงข้ามสามารถใช้ประโยชน์จากรูปแบบเพื่อถอดรหัสตัวเลขที่ควรจะแยกไม่ออก
  2. หากคุณกำลังใช้ RNG เพื่อจำลองอินพุต "สุ่ม" เช่นการทดสอบข้อผิดพลาดหรือการจำลองดังนั้น PRNG ทำให้วิธีการของคุณอ่อนแอ เมื่อคุณค้นพบข้อผิดพลาดใด ๆ จะมีข้อสงสัยที่จู้จี้: มีข้อบกพร่องที่ไม่ได้สังเกตเห็นด้วยรูปแบบของ PRNG ของฉัน แต่จะมีขึ้นถ้าฉันใช้ TRNG เท่านั้น? การค้นพบแบบจำลองของฉันอธิบายความจริงได้อย่างถูกต้องหรือว่าปรากฏการณ์ที่ฉันค้นพบเป็นเพียงสิ่งประดิษฐ์ของรูปแบบของ PRNG หรือไม่?

นอกพื้นที่เหล่านี้มันไม่สำคัญจริงๆ Caveat: ถ้า PRNG ของคุณแย่มากมันอาจไม่เหมาะสม - คุณไม่ต้องการสร้างเกม Craps ที่ลูกเต๋าขึ้นมาเสมอผู้เล่นของคุณจะไม่ชอบ

PRNG ของ Python ไม่ดีพออย่างไร

ไม่น่าเป็นไปได้มากที่คุณจะสามารถตรวจสอบข้อผิดพลาดของ PRNG จริงโดยใช้วิธีการง่าย ๆ ดังกล่าว การวิเคราะห์ทางสถิติของ RNGs เป็นศาสตร์ในสาขาของตนเองและการทดสอบที่ซับซ้อนบางอย่างนั้นมีให้ใช้เพื่อทำการเปรียบเทียบ "อัลกอริทึม" ของอัลกอริทึม สิ่งเหล่านี้ก้าวหน้ากว่าความพยายามอย่างง่ายของคุณ

นักพัฒนาซอฟต์แวร์ทุกคนที่สร้างไลบรารี่ในโลกแห่งความจริงเช่นนักพัฒนา Python ใช้การทดสอบทางสถิติเหล่านี้เป็นเครื่องมือวัดเพื่อดูว่าการใช้งาน PRNG ของพวกเขาดีพอหรือไม่ ดังนั้นยกเว้นกรณีการกำกับดูแลนักพัฒนาที่เกิดขึ้นจริงมันไม่น่าเป็นไปได้มากที่คุณจะสามารถตรวจสอบรูปแบบใน PRNG ที่ใช้งานจริงได้อย่างง่ายดาย นั่นไม่ได้หมายความว่าไม่มีรูปแบบ - PRNG มีรูปแบบตามคำนิยาม


0

โดยทั่วไปคุณไม่สามารถพิสูจน์แหล่งที่มาได้โดยการวิเคราะห์ทางคณิตศาสตร์ของผลลัพธ์คุณต้องการเช่นแบบจำลองทางกายภาพที่ระบุว่าแหล่งที่มานั้นสุ่ม (เช่นในการสลายกัมมันตรังสี)

คุณสามารถรันการทดสอบแบบแบตช์เพื่อค้นหาความสัมพันธ์ทางสถิติในข้อมูลผลลัพธ์ในกรณีนั้นข้อมูลได้รับการพิสูจน์แล้วว่าไม่ใช่แบบสุ่ม (แต่แหล่งที่มาแบบสุ่มสามารถมีเอาต์พุตแบบสุ่มไม่ได้หรือจะไม่สุ่มอย่างแท้จริงหากไม่สามารถระบุได้อย่างเฉพาะเจาะจง เอาท์พุท) มิฉะนั้นหากผ่านการทดสอบคุณสามารถพูดได้ว่าข้อมูลนั้นเป็นแบบสุ่มหลอก

ผ่านการทดสอบแบบสุ่มบางอย่างเท่านั้นหมายความว่าคุณมี PRNG ที่ดี (ตัวสร้างตัวเลขสุ่มหลอก) ซึ่งจะเป็นประโยชน์สำหรับแอปพลิเคชันที่ไม่ได้มีการรักษาความปลอดภัย

หากการรักษาความปลอดภัยมีส่วนเกี่ยวข้อง (เช่นการเข้ารหัสการสร้างกุญแจสำคัญการสร้างหมายเลขแบบสุ่มสำหรับการพนัน ... ) ไม่เพียงพอที่จะมี PRNG ที่ดีซึ่งจำเป็นต้องมีคุณสมบัติเพิ่มเติมเช่นฟังก์ชั่นเอาท์พุทที่ไม่ได้คาดเดาได้ง่ายจากผลลัพธ์ก่อนหน้า ฟังก์ชั่นจะต้องมีค่าใช้จ่ายในการคำนวณที่ต้องการ (จำกัด เพียงพอที่จะใช้งานได้ แต่สูงพอที่จะกำจัดความพยายามบังคับใช้สัตว์เดรัจฉานได้) ฮาร์ดแวร์ที่ใช้งานฟังก์ชั่น - หรืออุปกรณ์ในกรณีแปลก ๆ วันนี้มันเป็นอุปกรณ์อะนาล็อก - ไม่ควร ดัดแปลงได้อย่างง่ายดาย ฯลฯ

การมี PRNG ที่ดีจะมีประโยชน์ในเกมเพื่อสร้างรูปแบบใหม่และคาดเดาไม่ได้และในการเข้ารหัส - ยุ่งยากเกินกว่าที่จะอธิบายในโพสต์เดียวแค่คิดว่าเป็นบทบาทของหัวแม่มือสิ่งที่ออกจากกระบวนการเข้ารหัสควรหลอกแบบสุ่มไม่แสดงรูปแบบ ที่สามารถเชื่อมโยงข้อมูลที่เข้ารหัสไว้ก่อนหน้านี้กับข้อมูลที่เข้ารหัสดังต่อไปนี้หรือเชื่อมโยงข้อมูลข้อความธรรมดากับข้อมูลที่เข้ารหัสหรือเชื่อมโยง ciphertexts ที่แตกต่างกันสองรายการ (ดังนั้นสามารถทำการเดาบนข้อความธรรมดา) ....


-5

เรื่องสั้น:

สร้างเมล็ดพันธุ์แบบสุ่มโดยใช้ไมโครวินาทีปัจจุบันของระบบ

เคล็ดลับนี้ค่อนข้างเก่าและยังใช้งานได้อยู่

ไม่รวมปัจจัยเดรัจฉานกำลังซึ่งฉันสามารถกำหนดชุดค่าผสมด้วย "เดิมพัน" ในตัวเลขที่เป็นไปได้ทั้งหมดและไม่ใช่จุดของคำถามนี้โดยเฉพาะเมื่อหมายเลขสุ่มส่วนใหญ่ถูกปัดเศษก่อนใช้งาน

สมมติว่าตัวอย่างฉันสามารถกำหนดเมล็ดพันธุ์ที่ใช้โดยใช้เพียง 10 ค่า ดังนั้นรู้เมล็ดฉันสามารถเดาค่าต่อไป

ถ้าฉันจะใช้เมล็ด = 1 แล้วฉันจะได้รับลำดับต่อไป:

1, 2, 3, 4, 5, 6, 7, 8, 9 ... (และฉันหักว่าเมล็ดใช้ id 1 และค่าถัดไป 10)

แต่จะเกิดอะไรขึ้นถ้าหากเปลี่ยนการส่งทุกค่า "nth" การเปลี่ยน seed โดยไมโครวินาทีปัจจุบันเป็นเล่ห์เหลี่ยมถูก (นั่นคือมันไม่ต้องใช้รอบ CPU มาก)

ดังนั้นตอนนี้ลำดับคือ: (เมล็ด = 1) 1, 2, 3, 4, 5, (เมล็ด = 2), 7, 9, 11, 13 ... (15?)

ในกรณีนี้:

a) ฉันไม่สามารถหักเมล็ดที่ใช้

b) เออร์โกฉันไม่สามารถเดาค่าต่อไปได้

c) การเดาเดียวที่ฉันทำได้คือการหักว่าเมล็ดต่อไปอาจเป็นจำนวนมาก

อย่างไรก็ตามอัลกอริธึมเครื่องกำเนิดแบบสุ่มที่ทันสมัยที่สุดใช้เทคนิคนี้ภายใต้ประทุน

ความจริงที่แท้จริงคือเราไม่ต้องการคอมพิวเตอร์ควอนตัมในการสร้างตัวเลขสุ่ม "จริง" ความไม่แม่นยำของผลึกคริสตัลของคอมพิวเตอร์ของเราทำหน้าที่เป็นเครื่องกำเนิดไฟฟ้าแบบสุ่มและประสิทธิภาพการสุ่มของ CPU ของเราก็แปรเปลี่ยนโดยไม่พิจารณา CPU มักจะทำงานหลายอย่างในเวลาเดียวกัน


2
นี่เป็นความคิดที่ไม่ดีและเป็นแหล่งที่มาของความเสี่ยงสำหรับสิ่งที่ต้องการลำดับที่ไม่สามารถคาดเดาได้ หากคุณใช้เวลาไมโครวินาทีคุณมีความเป็นไปได้เพียง 10 ^ 6 ของเมล็ดที่ค่อนข้างต่ำ
HoLyVieR

@HoLyVieR: มันเป็นความคิดที่ดีถ้าคุณใส่ใจเรื่องความปลอดภัย แต่ก็ไม่เลวเท่าที่คุณทำ: โดยปกติคุณจะใช้ไมโครวินาทีตั้งแต่เริ่มระบบ (หรือยูนิกซ์ยุค .... ) ซึ่งเพิ่มช่วงของค่าที่เป็นไปได้อย่างมาก
mikera

1
@mikera มันไม่ได้ดีไปกว่านี้เวลาที่ประมวลผลคำขอนั้นสามารถคาดเดาได้ เป็นช่องโหว่ของเวกเตอร์สำหรับฟังก์ชันการรีเซ็ตรหัสผ่านจำนวนมาก สคริปต์เหล่านั้นสร้างโทเค็น "สุ่ม" ด้วยเทคนิคของคุณและผู้โจมตีสามารถค้นหาโทเค็นที่สร้างขึ้นตั้งแต่การค้นหาเวลาที่ถูกประหารชีวิตค่อนข้างไม่สำคัญ ... ในเวลาเดียวกันกับที่ส่งคำขอรีเซ็ตรหัสผ่าน + - 150ms
HoLyVieR

แน่นอนว่าสถานการณ์นั้นแย่มาก แต่สถานการณ์ที่สถานะเริ่มต้นเมื่อระบบเริ่มต้นและผู้โจมตีไม่มีวิธีที่ดีในการคาดเดาว่าเวลาเริ่มต้นจะไม่เลวร้ายนัก คุณอาจมีไมโครวินาทีที่เป็นไปได้ 10 ^ 12 ที่สามารถเลือกได้ซึ่งทำให้การโจมตีบางประเภทเป็นไปไม่ได้ ต้องมีความชัดเจน: การแก้ปัญหาทั้งหมดเหล่านี้จะสวยไม่ดีจากมุมมองของการเข้ารหัสลับ แต่ค่าคงที่สำคัญ
mikera

สำหรับเซิร์ฟเวอร์ออนไลน์ข้อมูลสถานะการออนไลน์ของระบบบางครั้งจะถูกนำเสนอสู่สาธารณะ หรือคุณสามารถรับได้จากหน้าสถานะ "เหตุการณ์เกิดขึ้นอีกครั้ง" หรือคุณสามารถปิงรอสักครู่ใหญ่และสังเกตว่ามันอาจเป็นการรีบูตเครื่อง (ซึ่งจะให้เวลาหลายร้อยล้านครั้งในการตรวจสอบซึ่งค่อนข้างต่ำ)
Dereckson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.